gpt4 book ai didi

python - Django:为什么 Django 模型字段是类属性?

转载 作者:太空狗 更新时间:2023-10-29 17:29:00 27 4
gpt4 key购买 nike

在 Django 中,模型的字段被定义为类属性。

那么这意味着模型的所有实例都将共享这些字段的相同值,不是吗?

假设我有一个模型

class Tag(models.Model):
name = models.CharField(max_length=30)

我有一个表单,用户可以在其中提交标签。假设用户提交了 2 个标签:“Python”和“Django”。如果我在 View 中创建 2 个 Tag 实例:

t1 = Tag(name="Python")
t2 = Tag(name="Django")

因为 name 是一个类属性,所以 t1t2 不应该有相同的 name 值在这种情况下,哪个应该是“Django”?

但实际上 name 的行为更像是一个实例属性,而不是类属性。你能解释一下这是怎么回事吗?

最佳答案

不是,原因和这个一样:

>>> class Foo(object):
... bar = 'Foo attribute'
...
>>> f = Foo()
>>> f.bar
'Foo attribute'
>>> Foo.bar
'Foo attribute'
>>> f.bar = 'instance attribute'
>>> f.bar
'instance attribute'
>>> Foo.bar
'Foo attribute'

当您将属性分配给对象时,同名的类属性将被该对象的属性“遮盖”。然而,在属性查找中,如果相关对象未定义所述属性,则将返回类一。

在 Django 中,ORM 层使用这些类属性来生成转换为 SQL 查询和操作的机制(在幕后进行的深层元类魔法)。

编辑:回答您的问题--

要理解这一点,您需要了解一点 Python 的 data model .本质上,类和对象都有 namespace 。如果您查看它们的特殊 __dict__ 属性,这是显而易见的:

>>> print Foo.__dict__
{'__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute
'__weakref__' of 'Foo' objects>, '__module__': '__main__', 'bar': 'Foo attribute
', '__doc__': None}
>>> f = Foo()
>>> print f.__dict__
{}

当第一次创建对象f 时,它有一个空的命名空间。当您进行查找时,f.bar 会查找此命名空间(实际上是字典)。由于在那里找不到'bar' 属性,因此查找f 的类Foo。我们在那里找到了 'bar': 'Foo attribute'。这就是将要返回的内容:

>>> f.bar
'Foo attribute'

现在,当您将一个属性值分配给一个对象,并且该属性名称在其命名空间中尚不存在时,它会被创建:

>>> f.bar = 'instance attribute'
>>> print f.__dict__
{'bar': 'instance attribute'}
>>> f.bar
'instance attribute'

现在,您知道下一次查找 f.bar 时会发生什么! f.__dict__['bar'] 存在并将在我们查看 Foo 的命名空间之前返回。

当然,如果您的意图是始终访问和操作类的属性而不是实例的属性,则需要使用类的名称。

>>> Foo.bar
'Foo attribute'
>>> Foo.__dict__['bar']
'Foo attribute'

关于python - Django:为什么 Django 模型字段是类属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5943846/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com