2016-04-29 10 views
1

Alles, was ich will, ist die folgende SQL-Abfrage in Python Django-Syntax schreiben. Ich recherchierte viel, konnte aber nicht das gewünschte Ergebnis erzielen. Kannst du mir bitte Helfen.LINKE VERBINDUNG mit OR-Bedingung in Python django

SELECT * FROM thread 
    LEFT JOIN user 
    ON (thread.user1_id = user.id OR thread.user2_id = user.id) 
    WHERE user.id = 9 

Mein Modell:

class Thread(models.Model): 
     last_message = models.TextField(max_length=100) 
     user1_id = models.IntegerField() 
     user2_id = models.IntegerField() 
+0

Mögliche Duplikat [Django Filter - oder] (http://stackoverflow.com/questions/739776/django-filters-or) – Sayse

+0

die Frage ist – EducateYourself

+0

beitreten Die Frage ist unklar, Sie sollten zeigen, was Sie bisher versucht haben, um zu versuchen, es zu lösen. Sowie die relevanten Teile Ihrer Modelle. – Sayse

Antwort

1

Die genaue Abfrage kann nicht die Django ORM erstellt werden, ohne zu einem gewissen rohen SQL greifen zu müssen. Das Problem ist das ODER in der Join-Bedingung.

Da Sie jedoch keine Zeilen aus der Benutzertabelle auswählen, können Sie eine andere Abfrage mit denselben Ergebnissen erstellen.

Beginnen Sie mit der Definition Ihrer Modelle mit ForeignKeys.

Dann können Sie die Abfrage vorformulieren.

from django.db.models import Q 

threads = Thread.objects.filter(Q(user1__id=9) | Q(user2__id=9)) 

Die resultierende SQL wird in etwa so sein:

SELECT * FROM thread 
LEFT JOIN user AS user1 
ON (thread.user1_id = user1.id) 
LEFT JOIN user AS user2 
ON (thread.user2_id = user2.id) 
WHERE (user1.id = 9 OR user2.id = 9) 

Sie dies durch die Vermeidung der insgesamt beitreten verbessern.

# note the single underscore! 
threads = Thread.objects.filter(Q(user1_id=9) | Q(user2_id=9)) 

Generierung der folgenden SQL.

SELECT * FROM thread 
WHERE (user1_id = 9 OR user2_id = 9) 

Wenn Sie müssen auch die Benutzerinstanzen in derselben Abfrage zu erhalten, in dem Fall, dass Sie wirklich die Verbindung benötigen, haben Sie zwei Möglichkeiten.

  1. Verwenden Sie die erste Abfrage, die Joins enthält, und wählen Sie anschließend den richtigen Benutzer aus, der auf der ID in Python basiert.

    for thread in threads: 
        if thread.user1.id == 9: 
         user = thread.user1 
        else: 
         user = thread.user2 
    
  2. Oder verwenden Sie Raw SQL, um die genaue Abfrage zu erhalten, die Sie wollen. In diesem Fall können Sie die Modelle ohne ForeignKeys so verwenden, wie Sie sie definiert haben.

    threads = Thread.objects.raw(''' 
          SELECT *, user.id AS user_id, user.name as user_name FROM thread 
          LEFT JOIN user 
          ON (thread.user1_id = user.id OR thread.user2_id = user.id) 
          WHERE user.id = 9''') 
    for thread in threads: 
        # threads use the ORM 
        thread.id 
        # user fields are extra attributes 
        thread.user_id 
        thread.user_name 
    
+0

Ich habe den zweiten Weg, vielen Dank :) – EducateYourself

+0

Froh, zu helfen :) – Alvra

+0

kann ich request.user.id anstelle von 9 schreiben? – EducateYourself

Verwandte Themen