12

首先,我不喜欢网络编程。我碰到了 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

您的问题的本质是“这些类变量(我将 Field 对象分配给)如何突然变成 Django 的 ORM 中的实例变量(我分配给它)”?答案就是 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 表,因此此时它们处于 Class 级别是有意义的。

有关模型的更多信息,请参阅: 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 有模型管理器,允许“人”执行静态查询集操作。(https://docs.djangoproject.com/en/dev/topics/db/managers/#managers)。

所以例如

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