2016-07-25 9 views
1

Ich habe Verbraucher, die ConsumerEmails erhalten.Filtern von Objekten in Django basierend auf einem verwandten Feld, mit Ausnahme bestimmter Werte

class Consumer(Model): 
    pass 

class ConsumerEmail(Model): 
    summary = models.TextField() 
    consumer = models.ForeignKey(Consumer, related_name="emails") 

Ich möchte die Liste der Verbraucher, die keine E-Mails erhalten haben, oder keine E-Mails mit Ausnahme der, die sie bittet, ihre E-Mail-Adresse zu bestätigen. Das heißt, wenn ich die Tabellen in diesem Beispiel-links verbunden würde ich mag ids 1, 2, 3, aber nicht 4, 5.

 
╔════╤══════════════════════════════╤════════╗ 
║ id │ email.summary    │ select ║ 
╠════╪══════════════════════════════╪════════╣ 
║ 1 │ NULL       │ Yes ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 2 │ Sent email verification code │ Yes ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 3 │ Sent email verification code │ Yes ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 3 │ Sent email verification code │  ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 4 │ Sent email verification code │ No  ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 4 │ Update on your application │  ║ 
╟────┼──────────────────────────────┼────────╢ 
║ 5 │ Update on your application │ No  ║ 
╚════╧══════════════════════════════╧════════╝ 

Mein Versuch war:

Consumer.objects.exclude(~Q(emails__summary="Sent email verification code")) 

aber dies erzeugt die Abfrage

SELECT "api_consumer"."id" 
FROM  "api_consumer" 
WHERE NOT (
        NOT (
          "api_consumer"."id" IN 
          (
            SELECT u1."consumer_id" AS col1 
            FROM "api_consumeremail" U1 
            WHERE u1."summary" = 'sent email verification code'))) 

was nicht richtig ist. Was ist die richtige ORM-Abfrage?

+0

Sie Lookup nicht so komplex für Q-Objekte ist, haben Sie versucht, 'Consumer.objects.exclude (emails__summary =„Gesendete E-Mail Bestätigungscode“)' – kapilsdv

+0

Kapil, dass alle Benutzer zurückgibt, die nicht den Bestätigungscode erhalten haben, E-Mails, einschließlich derjenigen, die andere E-Mails erhalten haben. Ich möchte Nutzer, die keine E-Mails oder keine E-Mails erhalten haben, mit Ausnahme der Bestätigungscode-E-Mail. – Matthew

+0

Können Sie versuchen, Consumer.objects.filter (Q (Emails__isnull = True) | ~ Q (Emails__summary = "Gesendete E-Mail-Verifikationscode")) '..... Sie sagte auch, dass diejenigen, die andere E-Mails erhalten haben, sie auch ausschließen (Nicht viel klar für mich). – kapilsdv

Antwort

0
consumers_with_emails = ConsumerEmail.objects.exclude(
    summary="Sent email verification code" 
).values_list('consumer_id', flat=True).distinct() 

Consumer.objects.exclude(
    id__in=consumers_with_emails 
) 
+0

Danke, aber das funktioniert nicht, es zeigt Benutzer, die die Bestätigungs-E-Mail und andere E-Mails erhalten haben. Die Abfrage übersetzt "api_consumer" wählen. "Id" FROM "api_consumer" LEFT OUTER JOIN "api_consumeremail" ON ( "api_consumer". "Id" = "api_consumeremail". "Consumer_id") WHERE ( „api_consumeremail "." ID "IS NULL ODER" api_consumeremail "." Zusammenfassung "= 'gesendeter E-Mail-Bestätigungscode') – Matthew

+0

@Matthew Edited. Vielen Dank! –

+0

Danke, ich nahm den .annotate.filter Teil, der eine Ausnahme verursacht hat, und jetzt funktioniert es – Matthew

Verwandte Themen