Python djangos字段实例如何在模型中工作
在Django中,我对模型字段的工作方式感到困惑 您可以将它们定义为类变量 像这样的一节课:Python djangos字段实例如何在模型中工作,python,django,python-3.x,django-models,Python,Django,Python 3.x,Django Models,在Django中,我对模型字段的工作方式感到困惑 您可以将它们定义为类变量 像这样的一节课: class Foo: avar = "something here" 如果您创建了两个实例 f1 = Foo() f2 = Foo() 如果将avar设置为其他值,这将影响Foo的两个实例。那么,django如何在实例之间保持模型字段值的正确性呢?它是否只是使用基类变量创建表,然后查询数据库中的模型/表,以返回相应实例的正确字段值 或者,它是否在元类级别做了一些事情来推迟创建,直到模型\uu
class Foo:
avar = "something here"
如果您创建了两个实例
f1 = Foo()
f2 = Foo()
如果将avar设置为其他值,这将影响Foo
的两个实例。那么,django如何在实例之间保持模型字段值的正确性呢?它是否只是使用基类变量创建表,然后查询数据库中的模型/表,以返回相应实例的正确字段值
或者,它是否在元类级别做了一些事情来推迟创建,直到模型\uuuuu init\uuuuu
/\uuuu new\uuuuu
创建字段的唯一实例
更进一步。。。对于类似于
amodel=amodel.objects.get(*)
的东西,我可以看到Django将如何命中数据库,然后可能会返回一个模型类的实例,并为字段填充列值,这样您就可以正确访问属性amodel.field
。这是有道理的,但我不确定我是否理解这项工作的内部原理。这里发生了一些事情。首先,您所要做的就是在Foo对象中创建一个字符串,就像任何其他python对象一样。如果希望它成为数据库中的字段,则需要使用来自模型的类型。差不多
from django.db import models
class Foo(models.Model):
avar = models.CharField(max_length=255)
稍后,如果要对模型进行一些更改,请进行更改,然后调用save()方法更新数据库中的记录
f1.avar = "Something New"
f1.save()
常规类变量是类的属性。它不存储在数据库中(仅是)。在您的情况下,
avar
不是模型字段。它只是一个简单的python类变量
如果更改Foo
实例上的class变量,则它只会影响该实例。所有其他实例都不会受到影响。证明:
class Foo:
avar = 'Something'
a = Foo()
b = Foo()
a.avar = 'Something else'
print a.avar
> 'Something else'
print b.avar
> 'Something'
请注意,在a
上更改avar
不会在b
上更改它。还请注意,a.avar
的更改值仅在a
本身存在时才存在。此属性不存储在数据库中,如果从数据库加载新对象,它将只具有该类的默认avar
。Django使用收集所有字段,并在模型中收集它们。\u meta
。创建类后,字段不再是模型类本身的一部分:
class Foo(models.Model):
bar = models.CharField(max_length=255)
>>> Foo.bar
Traceback (most recent call last):
File "<input>", line 1, in <module>
Foo.bar
AttributeError: type object 'Foo' has no attribute 'bar'
不清楚你在问什么。您已经创建了两个单独的模型实例。它们是单独的对象,具有单独的属性,并且(如果要保存它们)在数据库中有单独的行。如果您想知道
模型.Model
内部如何工作,您可以在path/to/site packages/django/db/models/base.py
中查找代码,请参见class Model
@solarismoke OP拥有的是类属性而不是实例属性。因为对象是一个字符串,所以它实际上并不重要:分配给avar
会将名称重新绑定到局部变量,而不是更改class属性。然而,如果avar是可变的,这将是一个重要的区别。所以,蓬松松饼:我不认为设置avar
会影响这两个对象。除非您设置了Foo.avar
,但为什么要这样做呢?avar只是一个占位符。我试图强调常规类变量与django可能如何处理它们之间的问题。我认为你的回答实际上进一步突出了我的问题。您将f1.avar
设置为“新的东西”,但如果您要保存f2
,则只需将f2
的avar
设置为“新的东西”。或者至少从理论上讲,问题中的代码是如何工作的。因此,我对Django的字段实例类变量是如何工作的感到困惑/疑问。好吧,我完全误解了类变量当时是如何工作的。虽然这个答案解释了类变量是如何工作的,但它并没有回答Django字段实例如何在模型中工作的原始问题。看见
>>> class Foo(object):
... bar = 'test'
...
>>> f1 = Foo()
>>> f2 = Foo()
>>> f1.bar = 'shadowed'
>>> Foo.bar = 'changed'
>>> f1.bar
'shadowed'
>>> f2.bar
'changed'
>>> del f1.bar
>>> f1.bar
'changed'