根据相关字段在Django中过滤对象,但不包括某些值

根据相关字段在Django中过滤对象,但不包括某些值

问题描述:

我有消费者,他们接收ConsumerEmails。根据相关字段在Django中过滤对象,但不包括某些值

class Consumer(Model): 
    pass 

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

我想谁没有收到任何电子邮件,或者没有电子邮件,只是要求他们验证自己的电子邮件地址的一个消费者的名单。也就是说,在这个例子中,如果我离开,连接的表,我想ID为1,2,3,但不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  ║ 
╚════╧══════════════════════════════╧════════╝ 

我的尝试是:

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

但这生成查询

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'))) 

这是不对的。什么是正确的ORM查询?

+0

您查找是不是复杂对于Q对象,你有没有试过'Consumer.objects.exclude(emails__summary =“发送的电子邮件验证码”)' – kapilsdv

+0

卡皮尔,返回谁没有收到验证码的所有用户电子邮件,包括那些收到其他电子邮件的人。我希望没有收到电子邮件的用户,或者除验证码电子邮件外没有电子邮件的用户。 – Matthew

+0

你可以试试'Consumer.objects.filter(Q(emails__isnull = True)|〜Q(emails__summary =“发送电子邮件验证码”))'.....你也说过 - 收到其他邮件的那些人, (对我来说不太清楚)。 – kapilsdv

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

谢谢但不起作用,它显示收到验证电子邮件和其他电子邮件的用户。查询转换为SELECT “api_consumer”。 “ID” FROM “api_consumer” LEFT OUTER JOIN “api_consumeremail” ON( “api_consumer”。 “ID”= “api_consumeremail”。 “consumer_id”) WHERE( “api_consumeremail “。”id“IS NULL 或”api_consumeremail“。”summary“='发送电子邮件验证码') – Matthew

+0

@Matthew编辑。谢谢! –

+0

谢谢,我拿出了导致异常的.annotate.filter部分,现在它工作 – Matthew