首先,我不是网络编程 . 我碰到了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 回答
不是真正的答案,而是为了丰富:
不行
将工作 . 所以person的对象实例有名字和姓氏,但静态上下文Person没有 .
另请注意:Django具有模型管理器,允许“Person”执行静态查询集操作 . (https://docs.djangoproject.com/en/dev/topics/db/managers/#managers) .
所以例如
是的,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
你问题的实质是"how come these class variables (which I assign Field objects to) suddenly become instance variables (which I assign data to) in Django's 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源代码;这是一个很好的教育来源!