27👍
As Julien mentioned ordering on JSONField
is not yet supported in Django. But it’s possible via RawSQL
using PostgreSQL functions for jsonb. In OP’s case:
from django.db.models.expressions import RawSQL
RatebookDataEntry.objects.all().order_by(RawSQL("data->>%s", ("manufacturer_name",)))
17👍
Since Django 1.11, django.contrib.postgres.fields.jsonb.KeyTextTransform
can be used instead of RawSQL
from django.contrib.postgres.fields.jsonb import KeyTextTransform
qs = RatebookEntry.objects.all()
qs = qs.annotate(manufacturer_name=KeyTextTransform('manufacturer_name', 'data'))
qs = qs.order_by('manufacturer_name')
# or...
qs = qs.order_by('-manufacturer_name')
On Django 1.10, you’ll have to subclass KeyTransform
yourself:
from django.contrib.postgres.fields.jsonb import KeyTransform
class KeyTextTransform(KeyTransform):
operator = '->>'
nested_operator = '#>>'
_output_field = TextField()
Note: the difference between KeyTransform
and KeyTextTransform
is that KeyTransform
will return the JSON representation of the object, whereas KeyTextTransform
will return the value of the object.
For example, if data
is {"test": "stuff"}
, KeyTextTransform
will return 'stuff'
, whereas KeyTransform
will return '"stuff"'
(which can be parsed by json.loads
)
- Django ALLOWED_HOSTS with ELB HealthCheck
- Django global variable
- Django Rest Framework debug post and put requests
15👍
This question (and most of the answers) are for Django 1.9. However, Django versions 3.1 and newer support JSONField
on recent versions of MariaDB, MySQL, Oracle, PostgreSQL, and SQLite.
The behavior around creating/maintaining indexes on JSON fields may vary across database engines, but ordering should work with the exact syntax you have in your question:
RatebookDataEntry.objects.all().order_by("data__manufacturer_name")
Note that unless you do further filtering, this will include database rows where the manufacturer_name
key in the data
JSONField does not exist.
- PIL – libjpeg.so.8: cannot open shared object file: No such file or directory
- Accessing django project in LAN systems
10👍
Following Daniil Ryzhkov answer and Eugene Prikazchikov comment, you should be able to sort ASC and DESC on JSON data fields without annotating your queryset, by using both RawSQL
and OrderBy
. Also, you can perform case insensitive sorting by adding LOWER
:
from django.db.models.expressions import RawSQL, OrderBy
RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("LOWER(data->>%s)", ("manufacturer_name",)), descending=True))
To compare integers fields, you can cast as integer:
RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("cast(data->>%s as integer)", ("annual_mileage",)), descending=True))
- Django south: changing field type in data migration
- How do you divide your project into applications in Django?
- How can my Model primary key start with a specific number?
6👍
This is an upcoming feature which has already been added and will be released in Django 2.1, expected release of August 2018.
See https://code.djangoproject.com/ticket/24747 and https://github.com/django/django/pull/8528 for details.
3👍
The documentation does not mention this possibility. It seems you cannot use order_by based on a JSONfield for the moment.
- Django Test Client post() returns 302 despite error on view's post()
- Django – authentication, registration with email confirmation
0👍
I had to do the following to order by date (using to_date
). Assuming there’s another value in data
called created_date
(e.g. 03.06.2019).
RatebookDataEntry.objects.all().order_by(
OrderBy(
RawSQL("to_date(values->>%s, 'DD.MM.YYYY')", ("created_date",)),
descending=True,
)
)
- Is exposing a session's CSRF-protection token safe?
- How to test a Django on_commit hook without clearing the database?
- Enable PK based filtering in Django Graphene Relay while retaining Global IDs
- Django Foreign Key: get related model?