How to set the default of a JSONField to empty list in Django and django-jsonfield?
Question:
Question
What is the best way to set a JSONField
to have the default value of a new list in django
?
Context
There is a model where one of the fields is a list of items. In the case where there are no items set, the model should have an empty list.
Current solution
from django.models import Model
class MyModel(Model):
the_list_field = JSONField(default=[])
Is this the best way to do it? Should it be switched to use list
instead?
Thanks!
Answers:
According to the Django documentation for JSONField you should indeed use default=list
because using default=[]
would create a mutable object that is shared between all instances of your field and could lead to some objects not having an empty list as a default.
Please note that this does not only apply for django.contrib.postgres.fields.JSONField
but for all other kinds of objects and functions in Python in general.
Quote from the docs:
If you give the field a default, ensure it’s a callable such as list (for an empty default) or a callable that returns a list (such as a function). Incorrectly using default=[] creates a mutable default that is shared between all instances of
list
and dict
are callable, while []
and {}
are not (you can’t do []()
). So:
- Use
JSONField(default=list)
over JSONField(default=[])
- Use
JSONField(default=dict)
over JSONField(default={})
If you want to instantiate with some data you can do the following:
def jsonfield_default_value(): # This is a callable
return [0, 0] # Any serializable Python obj, e.g. `["A", "B"]` or `{"price": 0}`
class MyModel(Model):
the_list_field = JSONField(default=jsonfield_default_value)
Question
What is the best way to set a JSONField
to have the default value of a new list in django
?
Context
There is a model where one of the fields is a list of items. In the case where there are no items set, the model should have an empty list.
Current solution
from django.models import Model
class MyModel(Model):
the_list_field = JSONField(default=[])
Is this the best way to do it? Should it be switched to use list
instead?
Thanks!
According to the Django documentation for JSONField you should indeed use default=list
because using default=[]
would create a mutable object that is shared between all instances of your field and could lead to some objects not having an empty list as a default.
Please note that this does not only apply for django.contrib.postgres.fields.JSONField
but for all other kinds of objects and functions in Python in general.
Quote from the docs:
If you give the field a default, ensure it’s a callable such as list (for an empty default) or a callable that returns a list (such as a function). Incorrectly using default=[] creates a mutable default that is shared between all instances of
list
and dict
are callable, while []
and {}
are not (you can’t do []()
). So:
- Use
JSONField(default=list)
overJSONField(default=[])
- Use
JSONField(default=dict)
overJSONField(default={})
If you want to instantiate with some data you can do the following:
def jsonfield_default_value(): # This is a callable
return [0, 0] # Any serializable Python obj, e.g. `["A", "B"]` or `{"price": 0}`
class MyModel(Model):
the_list_field = JSONField(default=jsonfield_default_value)