在 Django 1.9 中,使用 JSONField(本机 postgres jsonb)的约定是什么?

In Django 1.9, what's the convention for using JSONField (native postgres jsonb)?

Django highly suggests notnull=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继承自FieldCharField,设置为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 在实例化模型时默认为 ""JSONFieldNone,而没有显式传递这些字段的值。

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 行为,我忘了考虑这一点。