2017-10-30 1 views
0

Wir haben derzeit einige Probleme mit dem Erstellen komplexer Q-Objekt-Abfragen mit mehreren inneren Joins mit Django.Django Query - Mehrere innere Joins

Das Modell, das wir erhalten möchten (im Beispiel "main" genannt), wird von einem anderen Modell mit einem Fremdschlüssel referenziert. Die Rückreferenz wird im folgenden Beispiel als "verwandt" bezeichnet. Es gibt viele Objekte des zweiten Modells, die sich alle auf das gleiche "Haupt" -Objekt beziehen, alle mit IDs und Werten.

Wir wollen alle "Haupt" -Objekte erhalten, für die ein verwandtes Objekt mit der ID 7113 existiert, das den Wert 1 UND ein verwandtes Objekt mit der ID 7114 hat, das den Wert 0 hat.

Dies ist unsere aktuelle Abfrage:

(Q(related__id=u'7313') & Q(related__value=1)) & (Q(related__id=u'7314') & Q(related__value=0)) 

Dieser Code ausgewertet

FROM `prefix_main` INNER JOIN `prefix_related` [...] WHERE (`prefix_related`.`id` = 7313 AND `prefix_related`.`value` = 1 AND `prefix_related`.`id` = 7314 AND `prefix_related`.`value` = 0) 

Was wir brauchen würde, ist ganz anders:

FROM `prefix_main` INNER JOIN `prefix_related` a INNER JOIN `prefix_related` b [...] WHERE (a.`id` = 7313 AND a.`value` = 1 AND b.`id` = 7314 AND b.`value` = 0) 

Wie kann ich die ORM-Abfrage neu schreiben zwei INNER JOINS verwenden/verschiedene verwandte Instanzen für die q-Objekte verwenden? Danke im Voraus.

Antwort

1

ich glaube nicht, dass Sie dafür Q-Objekte brauchen. Sie können einfach verwenden, um mehrere Filter wie folgt aus:

Mainmodel.objects.filter(related__id = 7114, related__value=1).filter(related__id = 7113, related__value=0) 

der erste Filter alle Objekte übereinstimmt, die ein ähnliches Objekt mit der ID 7114 und den Wert 1. Die zurückgegebenen Objekte werden gefiltert wieder mit der ID 7113 und dem Wert einmal haben 0 .

+0

Ja - diese Lösung funktioniert gut für UND-Bedingungen. Vielen Dank! Ich habe vergessen zu erwähnen, dass wir versuchen, eine Lösung zu finden, die auch für "OR" funktioniert - in unserem Anwendungsfall sollte diese Abfrage auch funktionieren: 'FROM' prefix_main' INNER JOIN 'prefix_related' [...] WHERE (' prefix_related '' id' = 7313 UND 'prefix_related'' value' = 1 ODER 'prefix_related'.id' = 7314 AND' prefix_related' 'value' = 0)' –

+1

@DanielK. In diesem Fall können Sie einfach folgendes tun: 'Mainmodel.objects.filter (Q (related__id = 7114, related__value = 1) | Q (related__id = 7113, related__value = 0))' – lilaLeon

+0

Unsere Filter werden dynamisch mit anderen Filterregeln kombiniert Wir bevorzugen daher eine einzige Lösung, die in beiden Fällen fast gleich funktioniert. Sehen Sie Änderungen, um beide Fälle mit einem Konstrukt abzudecken (entweder mit zwei Filteraufrufen oder mit Q-Objekten)? –