Django highly suggests 不将null=True
用于CharField和TextField基于字符串的字段,以便不为“无数据”提供两个可能的值(假设您是允许空字符串blank=True
)。这对我来说很有意义,我在所有项目中都这样做。
Django 1.9引入了JSONField,它使用了基础的Postgres jsonb
数据类型。上面的建议是否会延续到JSONField(即应使用blank=True
代替null=True
)?或者,应该使用null=True
代替?或者,应该使用default=dict
代替?要么, ..?为什么呢?
换句话说,当您只想允许一个“无数据”值时,新的本机JSONField的约定是什么?请支持你的答案,因为我做了很多研究,找不到任何正式的。提前谢谢。
答案 0 :(得分:27)
Django代码隐含的约定似乎是将空JSON值存储为NULL 而不是空字符串(这是CharField
的约定)。我之所以这样说是因为:
empty_strings_allowed
继承自Field
中的CharField
,并设为True
:
django/db/models/fields/__init__.py#L96
class Field(RegisterLookupMixin):
"""Base class for all field types"""
# Designates whether empty strings fundamentally are allowed at the
# database level.
empty_strings_allowed = True
...
但是, JSONField
会将其覆盖为False
:
django/contrib/postgres/fields/jsonb.py#L13
class JSONField(Field):
empty_strings_allowed = False
...
当您在未明确传递值的情况下实例化模型时,这会导致CharField
默认为""
和JSONField
到None
对于这些领域。
django/db/models/fields/init.py#L791
def get_default(self):
"""
Returns the default value for this field.
"""
if self.has_default():
if callable(self.default):
return self.default()
return self.default
if (not self.empty_strings_allowed or (self.null and
not connection.features.interprets_empty_strings_as_nulls)):
return None
return ""
因此,如果您想要JSONField
可选,则必须使用:
json_field = JSONField(blank=True, null=True)
如果您只使用blank=True
,就像使用CharField
一样,在尝试运行IntegrityError
而不通过{{1}时,您将获得MyModel.objects.create(...)
明确的参数。
答案 1 :(得分:4)
只是想补充一点,你应该避免在JSONField上设置默认值。我只是通过将其设置为{}
来制作小学生错误。结果是,如果没有显式设置,新对象将接收最后一个对象的值。它是JSONField中固有的Python行为,我忘了考虑它。