12

まず第一に、私は Web プログラミングには興味がありません。私はdjangoに出くわし、モデルについて少し読みました。次のコード (djangoproject.com から) に興味をそそられました。


class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __str__(self):
        # Note use of django.utils.encoding.smart_str() here because
        # first_name and last_name will be unicode strings.
        return smart_str('%s %s' % (self.first_name, self.last_name))

私のpythonの理解では、first_nameとlast_nameはクラス変数ですよね?それはコードでどのように使用されますか (Person.first_name または Person.last_name を設定すると、すべての Person インスタンスに影響すると思います)。なぜそのように使われるのですか?

4

3 に答える 3

22

あなたの質問の本質は、「DjangoのORMで、これらのクラス変数( Field オブジェクトを割り当てる)が突然インスタンス変数(データを割り当てる)になるのはなぜですか?」それに対する答えは、Pythonメタクラスの魔法です。

メタクラスを使用すると、Python クラスを作成するプロセス (そのクラスのインスタンスの作成ではなく、クラス自体の作成ではありません) にフックして変更することができます。

Django の Model オブジェクト (およびサブクラスであるモデル) にはModelBase メタクラスがあります。モデルのすべてのクラス属性を調べ、Field サブクラスのインスタンスであるすべてをフィールド リストに移動します。そのリストは_meta、モデルのクラス属性であるオブジェクトの属性として割り当てられます。MyModel._meta.fieldsしたがって、 、 またはを介し​​て、いつでも実際の Field オブジェクトにアクセスできますMyModel._meta.get_field('field_name')

このModel.__init__メソッドは、_meta.fieldsリストを使用して、モデル インスタンスの作成時にどのインスタンス属性を初期化する必要があるかを判断できます。

Django のソース コードに飛び込むことを恐れないでください。それは素晴らしい教育の源です!

于 2009-02-01T18:56:40.893 に答える
5

はい、first_name と last_name はクラス変数です。これらは、データベース テーブルに作成されるフィールドを定義します。first_name 列と last_name 列を持つ Person テーブルがあるため、この時点でそれらがクラス レベルであることが理にかなっています。

モデルの詳細については、http: //docs.djangoproject.com/en/dev/topics/db/models/を参照してください。

コードで Person のインスタンスにアクセスする場合、通常は Django の ORM を介してこれを行います。この時点では、基本的にインスタンス変数として動作します。

モデル インスタンスの詳細については、http: //docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocsを参照してください。

于 2009-02-01T11:57:17.077 に答える
0

本当の答えではありませんが、充実させるために:

Person.first_name 

動作しません

p = Person.objects.get(pk=x)
p.first_name

動作します。したがって、personのオブジェクトインスタンスには名前と姓がありますが、静的コンテキストのPersonにはありません。

また、注意:Djangoには、「Person」が静的クエリセット操作を実行できるモデルマネージャーがあります。(https://docs.djangoproject.com/en/dev/topics/db/managers/#managers)。

たとえば

peoples = Person.objects.all()
于 2012-03-08T14:45:43.390 に答える