2016-04-15 77 views
5

我有一个包含JSONField以下的Django模型:Django的1.9 JSONField ORDER_BY

class RatebookDataEntry(models.Model): 
    data = JSONField(blank=True, default=[]) 
    last_update = models.DateTimeField(auto_now=True) 

    class Meta: 
     verbose_name_plural = 'Ratebook data entries' 

而且数据字段包含此JSON:

{ 
    "annual_mileage": 15000, 
    "description": "LEON DIESEL SPORT COUPE", 
    "body_style": "Coupe", 
    "range_name": "LEON", 
    "co2_gkm_max": 122, 
    "manufacturer_name": "SEAT" 
} 

我可以排序的查询集由一个数据字段?此查询不起作用。

RatebookDataEntry.objects.all().order_by("data__manufacturer_name") 
+1

不是我所知道的(在一个queryset上),但是这种向我表明你实际上可能需要一个对象模型来代替“数据”而不是json – Sayse

+4

另外,使用'default = list'而不是'默认= []',否则你最终会在不同的实例之间共享同一个列表。 – Alasdair

回答

16

由于Julien提到在JSONField上的排序在Django中尚未得到支持。但是可以通过RawSQL使用PostgreSQL functions for jsonb。在OP的情况:

from django.db.models.expressions import RawSQL 
RatebookDataEntry.objects.all().order_by(RawSQL("data->>%s", ("manufacturer_name",))) 
+4

如果你想DESC排序,你可以引入带注释的字段并按顺序排列。像这样:RateBookDataEntry.objects.annotate(manufacturer_name = RawSQL(“data->>%s”,(“manufacturer_name”,))。order_by(“ - manufacturer_name”) –

+0

为了防止任何人只查看接受的答案,这是Django 2.1中的一个功能,请参阅我对链接的回答。 – yekta

0

该文件没有提到这种可能性。看来你暂时不能使用基于JSONfield的order_by。

+0

是的。我也没有发现关于在文档中订购的任何提及。 –

4

Daniil Ryzhkov答案和Eugene Prikazchikov评论,你应该能够不标注您的查询集同时使用RawSQLOrderBy排序JSON数据字段ASC和DESC。此外,您还可以通过添加LOWER执行不区分大小写的排序:

from django.db.models.expressions import RawSQL, OrderBy 

RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("LOWER(data->>%s)", ("manufacturer_name",)), descending=True)) 

比较整数字段,可以强制转换为整数

RatebookDataEntry.objects.all().order_by(OrderBy(RawSQL("cast(data->>%s as integer)", ("annual_mileage",)), descending=True))