2016-04-15 123 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))