r3d*_*00d 8 python django postgresql
我有点迷失了解释Django对PostgreSQL JSONField应用默认值的解释:
如果为该字段指定默认值,请确保它是可调用的,例如
dict(对于空默认值)或返回dict(例如函数)的可调用对象.错误地使用default={}会创建在JSONField的所有实例之间共享的可变默认值.
所以在我的模型文件中,我已经声明了默认值
foo = JSONField(default=dict())
Run Code Online (Sandbox Code Playgroud)
但是,当我为新字段生成迁移操作时,这就是结果
migrations.AddField(
model_name='bar',
name='foo',
field=django.contrib.postgres.fields.jsonb.JSONField(default={}))
Run Code Online (Sandbox Code Playgroud)
我只是不确定这个结果是否符合文档的建议.这是有效的,还是应该修改生成的默认值来调用dict()?
Wil*_*sem 17
一个可调用的对象x是可以被调用,因此x()是有效的,因为它不是可调用的(因为函数某处产生错误虽然可以在通话过程中出现错误,例如)不会引发错误.
dict()实际上完全等同于{},这不是可调用的,因为{}(),不会导致构造任何东西.但dict另一方面,它本身就是对dict类的引用,如果我们称之为它,我们构造一个新的 dict.所以我们应该写它:
# no brackets! We do not make a call, but pass the callable
foo = JSONField(default=dict)Run Code Online (Sandbox Code Playgroud)
所以我们不调用dict类,我们传递对类的引用,这些类是可调用的:如果你调用它们,通常构造一个新实例(尽管可以改变这种行为).
传递callable在这里至关重要,因为否则Django每次都会使用对同一个字典的引用.因此,更改其中一个词典将更改其他更改引用的词典.如果你存储字典并重新加载它,那么这将是一个不同的字典,但只要你构建了两个模型,在同一个Python运行期间,这些将是相同的对象.
但是,如果您传递一个函数,则会调用该函数,从而生成两个不同的对象,都是空字典.但是第一本字典的更改不会反映在第二本字典中.
例如,如果您想要使用包含数据的字典初始化JSON字段,而不是写入,则必须将其定义为:default={'a': 4}
def default_somemodel_dict():
return {'a': 4}
class SomeModel(models.Model):
foo = JSONField(default=default_somemodel_dict)Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2346 次 |
| 最近记录: |