Python Django多对多查询的逻辑or返回重复的结果

Python Django多对多查询的逻辑or返回重复的结果,python,sql,django,many-to-many,Python,Sql,Django,Many To Many,我有这样多对多关系的模型: class Contact(models.Model): name = models.TextField() address = models.TextField() class Mail(models.Model): to = models.ManyToManyField(Contact, related_name='received_mails') cc = models.ManyToManyField(Contact, rela

我有这样多对多关系的模型:

class Contact(models.Model):
    name = models.TextField()
    address = models.TextField()

class Mail(models.Model):
    to = models.ManyToManyField(Contact, related_name='received_mails')
    cc = models.ManyToManyField(Contact, related_name='cced_mails')
我想获取给定电子邮件的“收件人”字段或“抄送”字段中的联系人集。让我们试试:

>>> Contact.objects.filter(received_mails__id=111)
[<Contact: fred@foo.com>]
>>> Contact.objects.filter(cced_mails__id=111)
[<Contact: joe@bar.com>]

当SQL返回所有匹配的记录时,Django尽职尽责地将它们映射到对象。您正在寻找的是
.distinct()
queryset方法,该方法可以使SQL将所有重复的行折叠为一行。

成功了,谢谢。(很抱歉,我还不能投票支持你。)这将使用SELECT DISTINCT而不是SELECT更改查询。我不知道没有它你怎么能得到这么多的副本,但我眼前的问题已经解决了。你将为
mailshareapp\u联系人
×(
mailshareapp\u mail\u to
+
NULL
)×(
mailshareapp\u mail\u cc
+
NULL
)至少满足一个JOIN和一个WHERE子句的。顺便说一句,如果以上回答了你的问题,你可以随时将其标记为已接受的回答。
>>> Contact.objects.filter(Q(received_mails__id=111) | Q(cced_mails__id=111))
[<Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, '...(remaining elements truncated)...']
SELECT `mailshareapp_contact`.`id`, `mailshareapp_contact`.`name`,
`mailshareapp_contact`.`address` FROM `mailshareapp_contact`
LEFT OUTER JOIN `mailshareapp_mail_to`
ON (`mailshareapp_contact`.`id` = `mailshareapp_mail_to`.`contact_id`)
LEFT OUTER JOIN `mailshareapp_mail_cc`
ON (`mailshareapp_contact`.`id` = `mailshareapp_mail_cc`.`contact_id`)
WHERE (`mailshareapp_mail_to`.`mail_id` = 111
OR `mailshareapp_mail_cc`.`mail_id` = 111 )