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

后端 未结 2 1377
南旧
南旧 2021-01-03 19:41

Django highly suggests not to use null=True for CharField and TextField string-based fields in order not to have two possible values for \"no d

2条回答
  •  执笔经年
    2021-01-03 20:19

    The convention implied from the Django code seems to be to store null JSON values as NULL as opposed to as an empty string (as is the convention for the CharField). I say this because of the following:

    The empty_strings_allowed is inherited from Field in CharField, and is set to 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, however, overrides it with False:

    django/contrib/postgres/fields/jsonb.py#L13

    class JSONField(Field):
        empty_strings_allowed = False
        ...
    

    This causes CharField's to default to "" and JSONField's to None when you instantiate a model without explicitly passing the values for these fields.

    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 ""
    

    Therefore, if you want to make a JSONField optional, you have to use:

    json_field = JSONField(blank=True, null=True)
    

    If you use only blank=True, as you would for CharField, you'll get an IntegrityError when trying to run MyModel.objects.create(...) without passing a json_field argument explicitly.

提交回复
热议问题