2012-08-17 9 views
18

だから私はこのようにDjangoのモデルを作成することができますDjangoモデルはどのように機能しますか?

from django.db import models 

class Something(models.Model): 
    title = models.TextField(max_length=200) 

と私はこのようにそれを扱うことができます:

thing = Something() 
#set title 
thing.title = "First thing" 
#get title 
thing.title 

すべての作品、それは必要がありますが、私はそれがどのように動作するかを理解したいと思いますよう。ライン上の非DjangoのPythonコードで

title = models.TextField(max_length=200) 

はタイプmodels.TextFieldのクラス変数タイトルを定義し、私はこのようにもそれにアクセスすることができます:私は何かのインスタンスを作成するときにthing.__class__.titlelink

しかし、ジャンゴに私は突然、テキストを取得/設定できるタイトル属性を持っています。そして、thing.__class__.titleでそれにアクセスできません。明らかにthing.titleを実行するとき、私はクラス変数 "title"にアクセスしていませんが、属性/プロパティを生成していますか?

私はフィールドがthing._meta.fieldsに終わったことを知っていますが、どうですか? 何が起こっているの?

1、Djangoはバックグラウンドでプロパティ "title"を作成しますか?

2、変数 "title"はどうなりましたか?

答えて

16

私はそのDjangoのドキュメントにはsay on thisがあるものを打つのは難しいと思います。

Modelクラスは、(base.pyを参照)新しいクラスを作成するために使用するクラスとして(もbase.pyで)ModelBaseを定義メタクラス属性を持っています。だからModelBase。 新しいが呼び出され、この新しいExampleクラスが作成されます。そのインスタンスではなく、ここでクラスオブジェクトを作成していることに気づくことが重要です。言い換えれば、Pythonは現在の名前空間のExampleの名前に最終的にバインドされるものを作成しています。

基本的にmetaclassは、クラス自体の作成方法を定義します。作成中に、追加の属性/メソッド/何かをそのクラスにバインドすることができます。このstackoverflow answerが与える例は、同様にクラス

# remember that `type` is actually a class like `str` and `int` 
# so you can inherit from it 
class UpperAttrMetaclass(type): 
    # __new__ is the method called before __init__ 
    # it's the method that creates the object and returns it 
    # while __init__ just initializes the object passed as parameter 
    # you rarely use __new__, except when you want to control how the object 
    # is created. 
    # here the created object is the class, and we want to customize it 
    # so we override __new__ 
    # you can do some stuff in __init__ too if you wish 
    # some advanced use involves overriding __call__ as well, but we won't 
    # see this 
    def __new__(upperattr_metaclass, future_class_name, 
       future_class_parents, future_class_attr): 

     attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__')) 
     uppercase_attr = dict((name.upper(), value) for name, value in attrs) 

     return type(future_class_name, future_class_parents, uppercase_attr) 

のすべての属性を大文字、モデルのDjangoのメタクラスは、あなたがクラスに適用した属性を消化し、検証のために種々の有用な属性を追加することができますの/ etc、方法と無関係も含めて

+1

おかげでフィールドを移動します。 djangoproject.com!私はdocs.djangoproject.comで説明を探していただけです – Michal

+0

メタクラスは属性やメソッドなどを追加できますが、CharField型のクラス変数titleが明確に削除されているので属性/メソッドなども削除できますか?それとも? – Michal

+0

@Michal確かに、すべてのpython属性は '__dict__'に格納されています。その '__dict__'を操作することによって、あなたは何でもできるのです。 –

2

pythonは非常に強力で、開発者はintrespectionを使用することができます。

djangoは多くのメタクラスを使用します。そのモデルのように見えます。モデルもそれを使用します。私はメタクラスは、まさにこのようなフィールドの属性クラスを受講し、これらのモデルのサブクラスのすべての新しいインスタンスに対して、良いと考え変数を作成すると思いますbase.py

class Model(object): 
    __metaclass__ = ModelBase 

\ \モデル\デシベルジャンゴ で参照してください。

1)はい、ジャンゴプロパティのインスタンス変数を作成し、「タイトル」automaticaly 2)と同じように、メタクラスは...メタクラスにコード上のドキュメントへのリンクのための

関連する問題