逻辑或Django的多对多查询返回重复的结果 [英] Logical or of Django many to many queries returns duplicate results
问题描述
我的模型具有许多这样的关系:
I have models with many to many relationships like this:
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')
我想获取给定电子邮件的收件人"字段或抄送"字段中的一组联系人.让我们尝试一下:
I want to obtain the set of contacts that are in either the to field or the cc field for a given email. Let's try:
>>> Contact.objects.filter(received_mails__id=111)
[<Contact: fred@foo.com>]
>>> Contact.objects.filter(cced_mails__id=111)
[<Contact: joe@bar.com>]
到目前为止,一切都很好.每种关系我们都有一个联系人.但最好将它们都放入同一个QuerySet中.
So far so good. We have one contact for each relationship. But it would be nice to get them both into the same QuerySet.
>>> 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)...']
发生了什么事?我觉得这与在SQL中联接表有关,但是我真的不了解在多对多关系的幕后情况.可能是我想做的事很愚蠢,或者有一种简单的方法可以做到.无论哪种方式,我都很高兴能被设置在正确的道路上.
What happened? I have a feeling it is something to do with joining tables in SQL, but I don't really understand what is happening under the hood with many to many relationships. It could be that what I am trying to do is stupid, or that there is an easy way to do it. Either way, I'm happy to be set on the right path.
这是QuerySet的查询:
this is the query of the QuerySet:
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 )
推荐答案
随着SQL返回所有匹配的记录,Django会忠实地将它们映射到对象.您正在寻找的是.distinct()
queryset方法,该方法使SQL将所有重复的行折叠为一个.
As SQL returns all matching records, Django dutifully maps them to objects. What you're looking for is the .distinct()
queryset method that makes SQL collapse all duplicate rows into one.
这篇关于逻辑或Django的多对多查询返回重复的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!