Django模型字段如何工作?

时间:2009-02-01 11:43:27

标签: python django django-models

首先,我不是网络编程。我碰到了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实例)?为什么这样使用?

3 个答案:

答案 0 :(得分:20)

你的问题的本质是“为什么这些类变量(我将Field对象赋予)突然变成实例变量(我将数据分配给Django的ORM”)?答案就是Python metaclasses的神奇之处。

元类允许您挂钩并修改创建Python类的过程(不是创建该类的实例,创建类本身)。

Django的Model对象(以及你的模型,它们是子类)有一个ModelBase metaclass。它会查看模型的所有类属性,以及任何属于Field子类的实例,它会移动到字段列表中。该列表被指定为_meta对象的属性,该属性是模型的类属性。因此,您始终可以通过MyModel._meta.fieldsMyModel._meta.get_field('field_name')来获取实际的Field对象。

然后Model.__init__方法可以使用_meta.fields列表来确定在创建模型实例时应该初始化哪些实例属性。

不要害怕潜入Django源代码;这是一个很好的教育来源!

答案 1 :(得分:4)

是的,first_name和last_name是类变量。它们定义将在数据库表中创建的字段。有一个Person表,其中包含first_name和last_name列,因此此时它们处于Class级别是有意义的。

有关型号的更多信息,请参阅: http://docs.djangoproject.com/en/dev/topics/db/models/

在代码中访问Person的实例时,通常是通过Django的ORM来实现这一点,此时它们基本上就像实例变量一样。

有关模型实例的更多信息,请参阅: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

答案 2 :(得分: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()