Django - 为什么在Model Classes Static中声明变量

Jam*_*nco 4 python django

我一直在阅读和使用Django一段时间.我仍然困惑的一件事是为什么我们在Django中创建的模型类由静态变量而不是成员变量组成.例如

class Album(models.Model):
    artist = models.CharField(max_length=128, unique=True)
    title = models.CharField(max_length=128, unique=True)
    genre = models.CharField(max_length=128, unique=True)

    def __unicode__(self):
        return self.name 
Run Code Online (Sandbox Code Playgroud)

我在这里阅读了这个解释python中静态变量和实例变量的页面但是我仍然对为什么Django希望模型中的字段变量是静态的而感到困惑?

knb*_*nbk 8

Django使用元类来创建模型类.正如类的__init__()方法创建一个新实例一样,元类的__new__()方法也会创建类本身.类主体中定义的所有变量,函数,属性等都将传递给__new__()函数.严格地说,仅仅在类体中定义变量不会创建静态/类变量 - 只有当__new__()函数接收变量并将其设置在类上时,它才是类/静态变量.

当涉及到字段和特殊Meta内部类时,Django 通过提供自定义__new__()方法来覆盖此行为.内部Meta类中的选项将转换为Options实例,而该实例将存储为Model._meta而不是Model.Meta.同样,您定义的任何字段都存储在Model._meta.fields类/静态变量中.

您会注意到在您的示例中,该类Album没有artist属性:Album.artist只会引发一个AttributeError.这是因为元类将字段从类移动到Album._meta.fields.Albumdo 实例有一个artists属性,但这不是字段.相反,它是与该字段相关的数据库值.__init__模型的方法用于使用self._meta.fields传递给的值__init__或使用默认值填充任何属性,以确保实例变量存在.

只有类变量传递给__new__方法.如果你要将一个字段定义为一个实例变量__init__,那么该字段将永远不会被传递给Model._meta.fields,而且Django根本不知道该字段.您将能够访问Album.artist,但这将是实际的字段实例,而不是相关的数据库值.基本上你会错过将模型变成模型的魔力.