我稍微解释了将Django's解释为将默认值应用于PostgreSQL JSONField:
如果您为该字段指定默认值,请确保它是可调用的,例如
dict
(对于空默认值)或可调用的返回dict
(例如函数)。使用default={}
错误地创建了一个在JSONField的所有实例之间共享的可变默认值。
所以在我的模型文件中,我已经宣布默认为
foo = JSONField(default=dict())
然而,当我为新字段生成迁移操作时,这是结果
migrations.AddField(
model_name='bar',
name='foo',
field=django.contrib.postgres.fields.jsonb.JSONField(default={}))
我不确定此结果是否符合文档的建议。这是有效的,还是应该修改生成的默认值来调用dict()
?
答案 0 :(得分:10)
callable 是可以调用的对象x
,因此x()
有效,并且不会引发错误,因为它是不可调用(尽管在调用期间可能存在错误,例如因为函数某处产生错误)。
dict()
实际上完全等同于到{}
,这不是可调用的,因为{}()
不会导致构造任何内容。但另一方面, dict
本身是dict
类的引用,如果我们调用它,我们构造一个 new {{1 }}。所以我们应该这样写:
dict
所以我们不调用# no brackets! We do not make a call, but pass the callable
foo = JSONField(default=dict)
类,我们将引用传递给类,这些类是可调用的:如果你调用它们,那么你通常构造一个新实例(尽管可以更改此行为)。
传递callable在这里至关重要,因为否则Django每次都会使用对相同字典的引用。因此,更改其中一个词典将更改其他更改引用的词典。如果你存储字典并重新加载它,那么这将是一个不同的字典,但只要你构建了两个模型,在同一个Python运行期间,这些将是相同的对象。
如果您传递函数,则会调用该函数,从而生成两个不同的对象,这两个对象都是空字典。但是对第一本词典的更改不会反映在第二本词典中。
如果您想要使用包含数据的字典初始化JSON字段,而不是编写 ,则必须将其定义为:dict
default={'a': 4}