2011-10-12 9 views
11

を複製:論理またはジャンゴの多くのクエリには多くのリターンは、私はこのような多くの関係に多くとのモデルを持っている結果

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

私は、フィールドまたはCCのいずれかにある連絡先のセットを取得したいです特定の電子メールのフィールド。試してみましょう:

>>> Contact.objects.filter(received_mails__id=111) 
[<Contact: [email protected]>] 
>>> Contact.objects.filter(cced_mails__id=111) 
[<Contact: [email protected]>] 

これまでのところとても良いです。私たちはそれぞれの関係について1つの連絡先を持っています。しかし、それらを両方とも同じQuerySetに登録するとよいでしょう。

>>> Contact.objects.filter(Q(received_mails__id=111) | Q(cced_mails__id=111)) 
[<Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, <Contact: [email protected]>, '...(remaining elements truncated)...'] 

どうしましたか?私はSQLでテーブルを結合することとは何かを感じていますが、多対多の関係で何が起こっているのかは分かりません。私がしようとしているのは、愚かなこと、あるいは簡単なやり方があることかもしれません。いずれにせよ、私は正しい道のりで幸せになれる。

編集:これは、クエリセットのクエリです:

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) 

答えて

16

SQLが一致するすべてのレコードを返したように、Djangoは律儀オブジェクトにマッピングします。あなたが探しているのは、.distinct()クエリーセットメソッドで、SQLはすべての重複行を1つにまとめます。

+0

これは、おかげで、ありがたいことです。 (申し訳ありませんが、私はあなたをまだ投票できません)SELECTだけでなくSELECT DISTINCTを使用してクエリを変更します。私はあなたがそれなしで多くの複製を得る方法を見ませんが、すぐに問題は解決します。 –

+0

少なくとも1つのJOINと1つのWHERE句を満たす 'mailshareapp_contact'×(' mailshareapp_mail_to' + 'NULL')×(' mailshareapp_mail_cc' + 'NULL')の組み合わせごとに別々の行が得られます。ところで、あなたの質問に答えた場合は、常にそれを受け入れられた回答としてマークすることができます。 – patrys

関連する問題