逻辑或Django多次查询返回重复的结果

时间:2011-10-12 12:52:30

标签: 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, related_name='cced_mails')

我想获取给定电子邮件的to字段或cc字段中的联系人集。我们试试吧:

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

到目前为止一切顺利。我们为每个关系都有一个联系人。但将它们放入同一个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中连接表有关,但我真的不明白在很多关系下发生了什么。可能是我想做的事情是愚蠢的,或者有一种简单的方法可以做到这一点。无论哪种方式,我都很高兴能够走上正确的道路。

编辑:这是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 )

1 个答案:

答案 0 :(得分:17)

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