首先,我不是网络编程。我碰到了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实例)?为什么这样使用?
答案 0 :(得分:20)
你的问题的本质是“为什么这些类变量(我将Field对象赋予)突然变成实例变量(我将数据分配给Django的ORM”)?答案就是Python metaclasses的神奇之处。
元类允许您挂钩并修改创建Python类的过程(不是创建该类的实例,创建类本身)。
Django的Model对象(以及你的模型,它们是子类)有一个ModelBase metaclass。它会查看模型的所有类属性,以及任何属于Field子类的实例,它会移动到字段列表中。该列表被指定为_meta
对象的属性,该属性是模型的类属性。因此,您始终可以通过MyModel._meta.fields
或MyModel._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()