2009-07-10 7 views
2

Betrachten Sie die Modelle:Django - Queryset Spanning null Beziehungen Q mit

#Models 
class A(models.Model): 
    fieldOfA = models.CharField(max_length = 4) 
class B(models.Model): 
    fieldOfB = models.CharField(max_length = 4) 
class C(models.Model): 
    classA = models.ForeignKey(A, blank=True, null=True) 
    classB = models.ForeignKey(B, blank=True, null=True) 

Wenn ich Objekte von C schaffen, ich sicherstellen, dass ein Objekt entweder eine classA oder classB Beziehung.

Ich bin auf der Suche nach einem einzelnen Abfrage-Set, die mir Objekte von C für bestimmte FieldOfA oder bestimmte FieldOfB Werte erhält.

Ich habe das versucht, aber es schlägt fehl (gibt [] zurück, obwohl es gültige Ergebnisse gibt).

#Views - assume double underscore in the query 
from django.db.models import Q 
my_query = C.objects.filter(Q(classA _ _isnull = False, classA _ _fieldOfA = 'foo') | Q(classB _ _isnull = False, classB _ _fieldOfB = 'foo')) 

Das Problem, das ich sehe, ist das '|' das ist das Angewendete. Zwei verschiedene Abfragesätze für Klasse A und Klasse B funktionieren einwandfrei. Wie kann ich ein einzelnes Abfrage-Set anwenden, damit dies funktioniert? Oder noch schlimmer, eine Möglichkeit, die einzelnen Abfragesätze zusammenzuführen.

Antwort

2

Wenn Sie sicher sein können, dass ein C entweder ein A oder ein B hat, aber nie beides, sind Ihre isnull-Einschränkungen redundant. Was passiert, wenn Sie Folgendes ausführen?

C.objects.filter(Q(classA__fieldOfA = 'foo') | Q(classB__fieldOfB = 'foo')) 

Wenn das immer noch nicht, manage.py shell funktioniert laufen und nach der obigen Abfrage ausgeführt wird (um sicherzustellen, dass settings.DEBUGTrue, überprüfen Sie die generierten SQL für die oben mit

>>> from django.db import connection 
>>> connection.queries() 

Was sehen Sie?

+0

Leider half die Beseitigung der Redundanz nicht. Das SQL hat zwei "LINKE ÄUSSEREN VERBINDUNGEN" für beide Qs (intern gefolgt von einem INNEREN VERBINDEN). Sollte das zweite Q nicht einen RIGHT OUTER JOIN haben? Die FeldB-Werte werden nicht wiederhergestellt. Danke für die Hilfe obwohl. Ich kettet (in gewisser Weise) die beiden Abfragesätze zusammen, was auch für mich funktioniert. Verwenden dieses Codeausschnitts - http://www.djangosnippets.org/snippets/1103/ – tjazz

2

Eigentlich Sie könnenQuerySet s in der gleichen Art und Weise kombinieren, wie so:.

C.objects.filter(classA__fieldOfA='foo') | C.objects.filter(classB__fieldOfB='foo')