2016-09-16 8 views
3

私はDjangoを少し読んでいます。私がまだ混乱していることの1つは、Djangoで作成するモデルクラスがメンバ変数ではなく静的変数で構成されている理由です。インスタンスDjango - モデルクラスで宣言された変数はなぜ静的です

class Album(models.Model): 
    artist = models.CharField(max_length=128, unique=True) 
    title = models.CharField(max_length=128, unique=True) 
    genre = models.CharField(max_length=128, unique=True) 

    def __unicode__(self): 
     return self.name 

のために私はしかし、私は、Djangoがモデル内のフィールド変数が静的で望んでいる理由としてはまだ混乱していますpythonで静的およびインスタンス変数を説明し、ここでthisページを読んで?

+0

モデルがPro Djangoの第3章(モデル)Marty Alchin、Apressによってどのように作成されたかに関する優れた記事があります –

答えて

6

Djangoはmetaclassを使用してモデルクラスを作成します。クラスの__init__()メソッドが新しいインスタンスを作成するのと同じように、メタクラスの__new__()メソッドはクラス自体を作成します。クラス本体で定義されたすべての変数、関数、プロパティなどは、__new__()関数に渡されます。厳密に言うと、クラス本体に変数​​を定義するだけでは、静的/クラス変数は作成されません。__new__()関数が変数を受け取ってクラスに設定した場合にのみ、クラス/静的変数になります。

カスタム__new__()メソッドを提供することで、Djangoはフィールドと特別なMeta内部クラスに対してこの動作をオーバーライドします。内側のMetaクラスのオプションはOptionsインスタンスに変換され、そのインスタンスはModel.MetaではなくModel._metaとして保存されます。同様に、定義するフィールドはクラス/静的変数ではなくModel._meta.fieldsに格納されます。

あなたはあなたの例では、クラスAlbumartist属性を持っていないことがわかります:Album.artistは単にAttributeErrorが発生します。これは、メタクラスがフィールドをクラスからAlbum._meta.fieldsに移動するためです。 Albumのインスタンスにはartistsという属性がありますが、のフィールドはではありません。代わりに、フィールドに関連するデータベース値です。モデルの__init__メソッドはself._meta.fieldsを使用して、__init__に渡される値、またはインスタンス変数が存在することを保証するための既定値のいずれかを持つ属性を設定します。

__new__メソッドには、クラス変数のみが渡されます。フィールドをインスタンス変数として__init__の中に定義する場合、そのフィールドは決してModel._meta.fieldsに渡されることはなく、Djangoは単にフィールドについて知らないだけです。 Album.artistにアクセスすることができますが、これは実際のフィールドインスタンスであり、関連するデータベース値ではありません。基本的には、モデルをモデルにする魔法が欠けているでしょう。

関連する問題