我对Django感到困惑的是模型的字段是如何工作的。
您将它们定义为类变量。
所以,这样的课程:
class Foo:
avar = "something here"
如果您创建了两个实例。
f1 = Foo()
f2 = Foo()
你将avar设置为别的东西,这会影响Foo
的两个实例。那么,django如何在实例之间保持模型字段值正确?它是否只是使用基类变量来创建表,然后在数据库中查询模型/表以返回各个实例的正确字段值?
或者,它是否在元类级别执行推迟创建,直到说出模型__init__
/ __new__
,然后创建字段的唯一实例?
进一步......对于像amodel = AModel.objects.get(*)
这样的东西我可以看到Django如何命中数据库,然后可能返回模型类的实例,并为字段填入列值,以便您可以访问该属性正确值amodel.field
。这是有道理的,但我不确定我是否了解这项工作的内部结构。
答案 0 :(得分:1)
常规类变量是类的属性。它不存储在数据库中(只有model fields)。在您的情况下,avar
不是模型字段。它只是一个简单的python类变量。
如果更改Foo
实例上的类变量,它只会影响该实例。所有其他实例不会受到影响。证明:
class Foo:
avar = 'Something'
a = Foo()
b = Foo()
a.avar = 'Something else'
print a.avar
> 'Something else'
print b.avar
> 'Something'
请注意,更改avar
上的a
不会在b
上更改a.avar
。另请注意,只有a
本身存在,avar
的更改值才会存在。此属性不存储在数据库中,如果从数据库加载新对象,它将只具有该类的默认<key>NSLocationAlwaysUsageDescription</key>
<array>
<string>Location is required to find out where you are</string>
</array>
<key>Privacy-Location Usage Description</key>
<string>Location is required to find out where you are.</string>
。
答案 1 :(得分:1)
Django使用metaclass收集所有字段,并在var classNameString = 'MyClass';
var myObject = eval("new " + classNameString + "()");
中收集它们。创建类后,字段不再是模型类本身的一部分:
Model._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'
)使用描述符,该描述符将是类属性,但这不是字段本身。
在实例化模型时,ForeignKey
将__init__
self._meta
中的None
所有字段,并指定默认值(如果您未提供任何字段默认值,通常为Foo._meta
)实例。这确保了每个字段都存在一个值,该值是一个实例变量,并且它可以是任何Python对象。
所有模型方法都使用>>> 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'
中的信息来确定哪些属性应被视为字段,哪些属于常规属性。
另请注意,当您覆盖实例上的类变量时,实际发生的是类变量被实例变量遮蔽。如果更改类本身的变量,则任何没有实例变量的实例也会更改值。如果删除实例上的变量,该值将恢复为(当前)类变量的值:
int redSensorValue = 0;
int greenSensorValue = 0;
int blueSensorValue = 0;
答案 2 :(得分:0)
这里发生了一些事情。首先,您所做的就是在Foo对象中创建一个字符串,就像任何其他python对象一样。如果您希望它是数据库中的字段,则需要使用模型中的类型。像
这样的东西from django.db import models
class Foo(models.Model):
avar = models.CharField(max_length=255)
稍后,如果要对模型进行一些更改,请进行更改,然后调用save()方法更新数据库中的记录。
f1.avar = "Something New"
f1.save()