在 Django 1.9 中,使用 JSONField(本机 postgres jsonb)的约定是什么?
In Django 1.9, what's the convention for using JSONField (native postgres jsonb)?
Django highly suggests not 将 null=True
用于 CharField 和 TextField 基于字符串的字段,以便 [=27= 没有两个可能的值](假设您允许带有 blank=True
的空字符串)。这对我来说很有意义,我在我的所有项目中都这样做。
Django 1.9 引入了 JSONField,它使用底层 Postgres jsonb
数据类型。上面的建议是否适用于 JSONField(即应该使用 blank=True
而不是 null=True
)?或者,应该改用 null=True
吗?或者,应该改用 default=dict
吗?要么, ..?为什么?
换句话说,当您只想允许一个 "no data" 值时,新的原生 JSONField 的约定是什么?请支持您的回答,因为我做了很多研究,但找不到任何官方信息。提前致谢。
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
一样,您将在尝试 运行 MyModel.objects.create(...)
而不通过时得到 IntegrityError
json_field
显式论证。
只是想补充一点,您应该避免在 JSONField 上设置默认值。我刚刚犯了一个小学生错误,将其设置为 {}
。结果是,如果未明确设置,新对象将接收最后一个对象的值。它是 JSONField 固有的 Python 行为,我忘了考虑这一点。
Django highly suggests not 将 null=True
用于 CharField 和 TextField 基于字符串的字段,以便 [=27= 没有两个可能的值](假设您允许带有 blank=True
的空字符串)。这对我来说很有意义,我在我的所有项目中都这样做。
Django 1.9 引入了 JSONField,它使用底层 Postgres jsonb
数据类型。上面的建议是否适用于 JSONField(即应该使用 blank=True
而不是 null=True
)?或者,应该改用 null=True
吗?或者,应该改用 default=dict
吗?要么, ..?为什么?
换句话说,当您只想允许一个 "no data" 值时,新的原生 JSONField 的约定是什么?请支持您的回答,因为我做了很多研究,但找不到任何官方信息。提前致谢。
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
一样,您将在尝试 运行 MyModel.objects.create(...)
而不通过时得到 IntegrityError
json_field
显式论证。
只是想补充一点,您应该避免在 JSONField 上设置默认值。我刚刚犯了一个小学生错误,将其设置为 {}
。结果是,如果未明确设置,新对象将接收最后一个对象的值。它是 JSONField 固有的 Python 行为,我忘了考虑这一点。