47👍
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.
3👍
Just wanted to add that you should avoid setting default values on JSONField. I just made a schoolboy error by setting it to {}
. The result is that new objects will receive the last object’s value if it was not explicitly set. Its a Python behaviour inherent in the JSONField, which I forgot to consider.
- [Django]-Django: How to check if the user left all fields blank (or to initial values)?
- [Django]-Django — User.DoesNotExist does not exist?
- [Django]-UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)