2011-10-12 30 views
11

tôi có các mô hình với nhiều đối với nhiều mối quan hệ như thế này:logic hoặc của Django nhiều để nhiều truy vấn trả về kết quả trùng lặp

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

Tôi muốn để có được những bộ danh bạ có trong một trong hai đến trường hoặc cc trường cho một email cụ thể. Hãy thử:

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

Cho đến nay rất tốt. Chúng tôi có một liên hệ cho mỗi mối quan hệ. Nhưng nó sẽ được tốt đẹp để có được cả hai vào cùng một 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]ar.com>, <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)...'] 

Điều gì đã xảy ra? Tôi có một cảm giác đó là một cái gì đó để làm với việc tham gia các bảng trong SQL, nhưng tôi không thực sự hiểu những gì đang xảy ra dưới mui xe với nhiều mối quan hệ nhiều. Nó có thể là những gì tôi đang cố gắng làm là ngu ngốc, hoặc rằng có một cách dễ dàng để làm điều đó. Dù bằng cách nào, tôi hạnh phúc được đặt trên con đường bên phải.

Edit: đây là câu hỏi của 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) 

Trả lời

16

Như SQL trả về tất cả các hồ sơ phù hợp với, Django nghiêm túc bản đồ chúng để các đối tượng. Những gì bạn đang tìm kiếm là phương pháp truy vấn .distinct() làm cho SQL thu gọn tất cả các hàng trùng lặp thành một.

+0

Điều đó đã thực hiện mẹo, cảm ơn. (Xin lỗi tôi không thể bỏ phiếu cho bạn.) Điều này thay đổi truy vấn bằng cách sử dụng SELECT DISTINCT thay vì chỉ SELECT. Tôi không thấy làm thế nào bạn có thể nhận được _so many_ bản sao mà không có nó, nhưng vấn đề trước mắt của tôi được giải quyết. –

+0

Bạn sẽ nhận được một hàng riêng biệt cho mỗi kết hợp của 'mailshareapp_contact' × (' mailshareapp_mail_to' + 'NULL') × (' mailshareapp_mail_cc' + 'NULL') thỏa mãn ít nhất một mệnh đề JOIN và một mệnh đề WHERE. Nhân tiện, nếu câu trả lời ở trên trả lời câu hỏi của bạn, bạn luôn có thể đánh dấu câu hỏi đó là câu trả lời được chấp nhận. – patrys

Các vấn đề liên quan