2016-04-15 23 views
5

Ho il seguente modello Django che contiene JSONField: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' 

E dati campo contiene questo JSON:

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

Can I sorta set di query da uno dei campi di dati ? Questa query non funziona.

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

Non che io sappia (su un queryset), ma questo tipo di mi indica che potresti effettivamente avere bisogno di un modello di oggetto per "dati" invece di JSON – Sayse

+4

Come parte, usa 'default = lista' invece di' default = [] ', altrimenti finirai con lo stesso elenco condiviso tra diverse istanze. – Alasdair

risposta

16

Come Julien ha menzionato l'ordinazione su JSONField non è ancora supportato in Django. Ma è possibile tramite RawSQL utilizzando PostgreSQL functions for jsonb. Nel caso di OP:

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

E nel caso in cui si desideri ordinare DESC, è possibile introdurre il campo annotato e ordinare da esso. In questo modo: RatebookDataEntry.objects.annotate (manufacturer_name = RawSQL ("data - >>% s", ("manufacturer_name",)). Order_by ("- manufacturer_name") –

+0

Nel caso in cui qualcuno stia solo guardando la risposta accettata, questa è una funzionalità di Django 2.1, vedere la mia risposta per i collegamenti. – yekta

0

La documentazione non menziona questa possibilità. Sembra che tu non possa usare order_by basato su un JSONfield per il momento.

+0

Sì. Non ho trovato alcuna menzione sull'ordinazione anche nei documenti. –

4

seguito Daniil Ryzhkov risposta e Eugene Prikazchikov commento, si dovrebbe essere in grado di ordinare ASC e DESC sui campi di dati JSON senza annotare il vostro set di query, utilizzando sia RawSQL e OrderBy. Inoltre, è possibile eseguire caso ordinamento insensitive aggiungendo LOWER:

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

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

Per confrontare i campi interi, si può lanciare come numero intero:

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