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

时间:2016-03-24 20:21:32

标签: python json django postgresql jsonb

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的约定是什么?请支持你的答案,因为我做了很多研究,找不到任何正式的。提前谢谢。

2 个答案:

答案 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默认为""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一样,在尝试运行IntegrityError而不通过{{1}时,您将获得MyModel.objects.create(...)明确的参数。

答案 1 :(得分:4)

只是想补充一点,你应该避免在JSONField上设置默认值。我只是通过将其设置为{}来制作小学生错误。结果是,如果没有显式设置,新对象将接收最后一个对象的值。它是JSONField中固有的Python行为,我忘了考虑它。