2009-02-01 36 views
10

首先,我没有进入网络编程。我碰到了django并阅读了一些关于模型的内容。我被下面的代码(从djangoproject.com)很感兴趣:Django模型字段如何工作?


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)) 

通过我的蟒蛇,FIRST_NAME的理解和姓氏是类变量,对不对?在代码中如何使用它(因为我猜想设置Person.first_name或Person.last_name会影响所有Person实例)?为什么这样使用?

回答

4

是的,first_name和last_name是类变量。他们定义将在数据库表中创建的字段。有一个Person表具有first_name和last_name列,所以在这一点上它们在Class级别上是有意义的。

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

当谈到访问代码的人的情况下,你通常是通过Django的ORM这样做,在这一点上,他们本质上表现为实例变量。

更多关于模型实例,请参见: http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs

+0

丹科舍恩安迪! – Geo 2009-02-01 13:00:00

+0

这里有一些很好的链接,但是“在这一点上它们本质上表现为实例变量”是一点手势,并非真正准确(或者至少没有解释任何东西)。 – 2009-02-01 18:44:16

19

你的问题的实质是“怎么来的这些类变量(我分配领域对象)突然变得实例变量(我分配数据)在Django的ORM“?答案就是Python metaclasses的魔力。

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

Django的模型对象(因此也是您的模型,它们是子类)有一个ModelBase metaclass。它会查看模型的所有类属性,以及它是Field子类的实例,它将移入字段列表中。该列表被分配为_meta对象的属性,该属性是模型的类属性。因此,您可以始终通过MyModel._meta.fieldsMyModel._meta.get_field('field_name')访问实际的Field对象。

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

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

0

不是一个真正的答案,但对于丰富:

Person.first_name 

将无法​​正常工作

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

会工作。所以人的对象实例具有名和姓,但静态上下文Person不具有。

另请注意:Django拥有允许“Person”执行静态查询集操作的模型管理器。 (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers)。

因此,例如

peoples = Person.objects.all()