Django's JSONField
actually stores the data in a Postgres JSONB
column, which is only available in Postgres 9.4 and later.
JSONField
is great when you want a more flexible schema. For example if you want to change the keys without having to do any data migrations, or if not all your objects have the same structure.
If you're storing data with static keys, consider using multiple normal fields instead of JSONField
s instead, as querying JSONField
can get quite tedious sometimes.
You can chain queries together. For example, if a dictionary exists inside a list, add two underscores and your dictionary query.
Don't forget to separate queries with double underscores.
from django.contrib.postgres.fields import JSONField
from django.db import models
class IceCream(models.Model):
metadata = JSONField()
You can add the normal **options
if you wish.
! Note that you must put
'django.contrib.postgres'
inINSTALLED_APPS
in yoursettings.py
Pass data in native Python form, for example list
, dict
, str
, None
, bool
, etc.
IceCream.objects.create(metadata={
'date': '1/1/2016',
'ordered by': 'Jon Skeet',
'buyer': {
'favorite flavor': 'vanilla',
'known for': ['his rep on SO', 'writing a book']
},
'special requests': ['hot sauce'],
})
See the note in the "Remarks" section about using
JSONField
in practice.
IceCream.objects.filter(metadata__ordered_by='Guido Van Rossum')
Get all ice cream cones that were ordered by people liking chocolate:
IceCream.objects.filter(metadata__buyer__favorite_flavor='chocolate')
See the note in the "Remarks" section about chaining queries.
An integer will be interpreted as an index lookup.
IceCream.objects.filter(metadata__buyer__known_for__0='creating stack overflow')
See the note in the "Remarks" section about chaining queries.
Ordering directly on JSONField
is not yet supported in Django. But it's possible via RawSQL using PostgreSQL functions for jsonb:
from django.db.models.expressions import RawSQL
RatebookDataEntry.objects.all().order_by(RawSQL("data->>%s", ("json_objects_key",)))
This example orders by data['json_objects_key']
inside JSONField
named data
:
data = JSONField()