2009-07-25 6 views
3

Ich habe wie die bekam Modelle in django:Django Eins-zu-eins Links Join ist null?

class User(models.Model): 
    name = models.CharField(max_length = 128) 

class Message(models.Model): 
    sender = models.ForeignKey(User, related_name = 'messages_sent') 
    recipient = models.ForeignKey(User, related_name = 'messages_recieved') 
    subject = models.CharField(max_length = 128) 
    body = models.CharField(max_length = 3500) 

class Response(models.Model): 
    message = models.OneToOneField(Message, primary_key = True) 
    reply = models.TextField() 

und ich versuche, alle Nachrichten für den Benutzer zu erhalten, die keine Antwort hat, etwas, das ich in SQL als schreiben würde:

select * from user u 
     join message m on (u.id = m.recipient_id) 
     left join response r on (m.id = r.message_id) 
where r.message_id = null 

ich würde denken, die natürliche Art und Weise, dies zu tun wäre:

u.messages_recieved.filter(response = None) 

oder

u.messages_recieved.filter(response__message_id__isnull = True) 

aber die generierten SQL endet immer sein bis:

WHERE ("project_message"."recipient_id" = 1 AND "project_message"."id" IS NULL) 

Bin ich etwas Dummes zu tun, oder ist das ein Fehler in Django?

Antwort

3

Versuchen:

user.messages_recieved.filter(response__isnull=True) 

die resultierende Abfrage ist:

SELECT "messaging_message"."id", "messaging_message"."sender_id", "messaging_message"."recipient_id", "messaging_message"."subject", "messaging_message"."body" FROM "messaging_message" LEFT OUTER JOIN "messaging_response" ON ("messaging_message"."id" = "messaging_response"."message_id") WHERE ("messaging_message"."recipient_id" = 1 AND "messaging_response"."message_id" IS NULL) 

die ich denke, ist richtig. Es macht in der Tat den linken äußeren Join und dann nach Zeilen mit ungültiger Antwortnachricht ID suchen.

u.messages_recieved.filter(response=None) 

funktioniert auch gut.

Ich benutze Django 1.1 RC aber das sollte in 1.0 funktionieren.

+0

Hah! Also könnte es in 1.1RC behoben sein, da keiner der oben genannten für mich in 1.0.2 funktioniert. Lass mich das überprüfen. – tpk

+0

So wurde es in 1.1 behoben. Gerade getestet auf die endgültige Version von 1.1. – tpk

+0

Das ORM hat in dieser neuen Version viele Verbesserungen erhalten. Interessanterweise habe ich nur mit 1.0.3 Alpha & 1.1 gearbeitet und beide haben dieselbe Abfrage erzeugt. – tarequeh

3

Etwas, das ich getan habe, wenn ein ähnliches Ergebnis zu erzielen versuchen, ist:

u.messages_received.filter(~Q(response__id__gt=0))