2009-05-10 7 views
320

Ich habe first_name, last_name & Alias ​​(optional), die ich suchen muss. Also brauche ich eine Abfrage, um mir alle Namen zu geben, die einen Alias-Satz haben.Filtern für leere oder NULL-Namen in einem Abfrage-Set

Nur wenn ich tun konnte:

Name.objects.filter(alias!="") 

Also, was das Äquivalent zu der oben ist?

Antwort

614

Sie können dies tun:

Name.objects.exclude(alias__isnull=True) 

Wenn Sie die bevorzugte Art und Weise null Werte und leere Strings ausschließen müssen, so zu tun, um Kette zusammen die Bedingungen wie folgt:

Name.objects.exclude(alias__isnull=True).exclude(alias__exact='') 

Verkettung dieser Methoden zusammen überprüft im Grunde jede Bedingung unabhängig: im obigen Beispiel schließen wir Zeilen aus, bei denen alias null oder eine leere Zeichenfolge ist, so dass Sie Erhalten Sie alle Name Objekte, die ein Nicht-Null-, Nicht-Leer-alias-Feld haben. Die erzeugte SQL würde in etwa so aussehen:

SELECT * FROM Name WHERE alias IS NOT NULL AND alias != "" 

Sie auch mehrere Argumente an einen einzigen Aufruf exclude passieren kann, die, dass nur Objekte sicherstellen würde, dass erfüllen jeden Zustand ausgeschlossen erhalten:

Name.objects.exclude(some_field=True, other_field=True) 

Hier werden Zeilen, in denen some_fieldundother_field wahr sind, ausgeschlossen, sodass wir alle Zeilen erhalten, in denen beide Felder nicht wahr sind. Der generierte SQL-Code wäre ein wenig wie folgt aussehen:

SELECT * FROM Name WHERE NOT (some_field = TRUE AND other_field = TRUE) 

Alternativ kann, wenn die Logik komplexer als das ist, könnten Sie Djangos Q objects:

from django.db.models import Q 
Name.objects.exclude(Q(alias__isnull=True) | Q(alias__exact='')) 

Für weitere Informationen siehe this page und this page in die Django-Dokumente.

Nebenbei: Meine SQL-Beispiele sind nur eine Analogie - der tatsächlich generierte SQL-Code wird wahrscheinlich anders aussehen. Sie erhalten ein tieferes Verständnis darüber, wie Django-Abfragen funktionieren, indem Sie sich das von ihnen generierte SQL ansehen.

+3

Ich glaube, dass Ihre Bearbeitung falsch ist: Chaining Filter erstellt nicht automatisch eine SQL 'OR' (nur in diesem Fall), erzeugt es eine SQL' AND'. Sehen Sie diese Seite als Referenz: https://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters Der Vorteil der Verkettung ist, dass Sie 'exclude' und' filter' zum Modellieren mischen können komplizierte Abfragebedingungen Wenn Sie ein echtes SQL 'OR' modellieren möchten, müssen Sie ein Django Q-Objekt verwenden: https://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q- Objekte Bitte bearbeiten Sie Ihre Bearbeitung, um dies zu reflektieren, da die Antwort stark irreführend ist, wie es aussieht. – shezi

+1

@shezi: Ich meinte es mehr als eine Analogie - ich wollte nicht, dass der eigentliche SQL-Code ist ein OR zu verwenden, um die Bedingungen zu fusionieren. Ich werde meine Antwort bearbeiten, um sie zu klären. –

+0

Denken Sie daran, dass es verschiedene Möglichkeiten gibt, diese Logik zu repräsentieren - zum Beispiel ist "NOT (A AND B)" äquivalent zu "NOT A OR NOT B". Ich denke, das macht die neuen Django-Entwickler, die SQL beherrschen, aber mit ORMs nicht vertraut sind, etwas verwirrend. –

31

Zunächst empfehlen die Django-Dokumente dringend, keine NULL-Werte für stringbasierte Felder wie CharField oder TextField zu verwenden. Lesen Sie die Dokumentation für die Erklärung:

https://docs.djangoproject.com/en/dev/ref/models/fields/#null

Lösung: Sie auch die Kette zusammen Methoden auf QuerySets, denke ich. Versuchen Sie folgendes:

Name.objects.exclude(alias__isnull=True).exclude(alias="") 

Das sollte Ihnen das Set geben, das Sie suchen.

+7

Ein Link zu wo es heißt, das wäre schön gewesen. https://docs.djangoproject.com/en/dev/ref/models/fields/#null – mpen

28
Name.objects.filter(alias__gt='',alias__isnull=False) 
+1

Ich bin mir nicht sicher, aber ich denke, die 'alias__isnull = False' Bedingung ist redundant. Wenn das Feld "Null" ist, wird es sicher durch die erste Klausel ausgeschlossen? – Bobble

+0

Abgesehen von meinem früheren Kommentar/Frage denke ich, dass die positive Logik hier leichter zu folgen ist als in einigen der anderen Antworten. – Bobble

+0

@Bobble, die von der Datenbank-Implementierung abhängen würde - [Bestellung ist an die Datenbank delegiert] (https://docs.djangoproject.com/en/1.10/ref/models/querysets/#latest) – wpercy

3

Von Django 1.8,

+0

Dies scheint wie ein " etwas, was du * kannst *, nicht etwas, was du * tun solltest. Es erhöht erheblich die Komplexität der Abfrage über zwei einfache Prüfungen. – Oli

Verwandte Themen