2016-04-15 9 views
5

Ich habe folgendes django Modell, das JSONField enthält: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' 

Und Daten Feld dieses json enthält:

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

Kann Art queryset ich von einem der Datenfelder ? Diese Abfrage funktioniert nicht.

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

Nicht, dass ich weiß (auf einem Abfrage-Set), aber diese Art von zeigt mir an, dass Sie tatsächlich ein Objektmodell für "Daten" anstelle von JSON benötigen – Sayse

+4

Als beiseite, verwenden Sie 'default = list' anstelle von' default = [] ', sonst wird dieselbe Liste zwischen verschiedenen Instanzen angezeigt. – Alasdair

Antwort

16

Wie Julien erwähnte Bestellung auf JSONField ist noch nicht in Django unterstützt. Aber es ist möglich über RawSQL mit PostgreSQL functions for jsonb. Im OP Fall:

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

Und für den Fall, dass Sie eine DESC-Bestellung wünschen, können Sie ein kommentiertes Feld und eine Reihenfolge eingeben. So: RatebookDataEntry.objects.annotate (Hersteller_Name = RawSQL ("Daten - >>% s", ("Hersteller_Name")). Order_by ("- Herstellername") –

+0

Nur für den Fall, dass jemand nur die akzeptierte Antwort betrachtet, Dies ist eine Funktion in Django 2.1, siehe meine Antwort für Links. – yekta

0

Die Dokumentation erwähnt diese Möglichkeit nicht. Es scheint, dass Sie order_by auf der Basis eines JSON-Feldes im Moment nicht verwenden können.

+0

Ja. Ich habe auch nichts über das Bestellen in Dokumenten gefunden. –

4

Nach Daniil Ryzhkov Antwort und Eugene Prikazchikov Kommentar, sollten Sie in der Lage sein, ASC und DESC zu sortieren auf JSON-Datenfeldern ohne Ihre queryset mit Anmerkungen versehen, um sowohl RawSQL und OrderBy verwenden. Auch können Sie auf Groß- und Kleinschreibung Sortierung durch Zugabe von LOWER ausführen:

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

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

auf ganze Zahlen Felder zu vergleichen, können Sie als Integer-Stimmen:

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