我有点迷失了解释 Django's将默认值应用于 PostgreSQL JSONField 的说明:
If you give the field a default, ensure it’s a callable such as
dict
(for an empty default) or a callable that returns adict
(such as a function). Incorrectly usingdefault={}
creates a mutable default that is shared between all instances of JSONField.
所以在我的模型文件中我声明了默认值
foo = JSONField(default=dict())
然而,当我为新字段生成迁移操作时,这就是结果
migrations.AddField(
model_name='bar',
name='foo',
field=django.contrib.postgres.fields.jsonb.JSONField(default={}))
我只是不确定这个结果是否符合文档的建议。这是有效的,还是我应该修改生成的默认值以调用 dict()
?
最佳答案
callable 是一个 x
对象,可以 调用,因此 x()
是有效的,并且不会引发错误,因为它不可调用(尽管在调用期间可能会出现错误,例如因为某处的函数产生错误)。
dict()
实际上完全等同于 {}
,它不是可调用的,因为 {}()
,不会导致构建任何东西。但另一方面,dict
本身是对 dict
类的引用,如果我们调用它,我们将构造一个新 字典
。所以我们应该这样写:
# no brackets! We do not make a call, but pass the callable
foo = JSONField(default=<b>dict</b>)
所以我们不调用dict
类,我们传递一个引用给类,这样的类是可调用的:如果你调用它们,您通常会构造一个新实例(尽管可以更改此行为)。
传递可调用对象在这里至关重要,否则 Django 每次都会使用对相同字典的引用。结果,对其中一个词典的更改将更改其他更改引用的词典。如果您存储字典并重新加载它,那么这将是一个不同的字典,但只要您构建了两个模型,在同一 Python 运行期间,它们将是相同的对象。
但是,如果您传递一个函数,该函数将被调用,从而产生两个不同 对象,它们都是空字典。但是对第一个字典的更改不会反射(reflect)在第二个字典中。
例如,如果您想要使用包含数据的字典来初始化 JSON 字段,而不是编写 ,这同样适用, 必须这样定义它:default={'a': 4}
def <b>default_somemodel_dict</b>():
return {'a': 4}
class SomeModel(models.Model):
foo = JSONField(default=<b>default_somemodel_dict</b>)
关于python - 在迁移文件中正确声明空 Django PostgreSQL JSONField 默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50632721/