2010-01-13 81 views
7

Tôi có cấu trúc này của các đối tượng mô hình:Lọc Nhiều người đến Nhiều mối quan hệ trong Django

Class A:
b = models.ManyToManyField("B") 
Class B:
c = models.ForeignKey("C") 
d = models.ForeignKey("D") 
Loại C:
d = models.ForeignKey("D") 

Đây là truy vấn Tôi đang cố gắng để có được:
Tôi muốn nhận tất cả các đối tượng B của đối tượng A, sau đó trong mỗi đối tượng B để thực hiện so sánh giữa đối tượng D và đối tượng cd .

Tôi biết rằng chỉ cần di chuyển trên bộ sưu tập B với vòng lặp và thực hiện so sánh này. Nhưng tôi lặn vào mối quan hệ ManyToMany, sau đó tôi nhận thấy tôi có thể làm như sau:

bObjects = A.objects.all().b 

q = bObjects.filter(c__d=None) 

này đang làm việc, nó mang lại cho tôi tất cả các đối tượng c với None d lĩnh vực. Nhưng khi tôi thử như sau:

q = bObjects.filter(c__d=d) 

Nó mang lại cho tôi d không xác định, nhưng d là một đối tượng như c trong đối tượng B.

gì có thể là vấn đề? Tôi sẽ rất vui nếu bạn đề xuất thêm cách để thực hiện tác vụ này. Tôi thường cố gắng viết truy vấn của mình trong một thao tác đơn lẻ với nhiều đối tượng phụ và không sử dụng vòng lặp.

+1

tất cả abc này là khó hiểu bạn có thể không chọn tên tốt hơn: D? – maazza

Trả lời

6

q = bObjects.filter(c_d=d) //Give me d not defined. but d is an object like c in the object B.

Hãy thử điều này:

from django.db.models import F 
q = bObjects.filter(c__d=F('d')) 

Đối với các câu hỏi từ nhận xét của bạn bên dưới, bạn có thể có 1 truy vấn sql thay vì 100 trong những cách sau:

1) nếu bạn có thể bày tỏ lựa chọn của bạn của một đối tượng về truy vấn (ví dụ: a.price < 10 và a.weight> 20) sử dụng:

B.objects.filter(a__price__lt=10, a__weight__gt=20, c__d=F('d')) 

hay này:

B.objects.filter(a__in=A.objects.filter(price__lt=10, weight__gt=20), c_d=F('d')) 

2) nếu bạn chỉ có một danh sách python của A đối tượng, sử dụng này:

B.objects.filter(a__pk__in=[a.pk for a in your_a_list], c__d=F('d')) 
+0

Cảm ơn tất cả, Nó hoạt động. Một câu hỏi nữa: Nếu tôi có danh sách các đối tượng của đối tượng chính A. Tôi có thể thực hiện truy vấn mà bạn đã viết với một dòng và không lặp lại trong danh sách A hay không và thực hiện tương tự. Chỉ đơn giản là tôi muốn lưu các lần truy cập vào id DB tôi có 100 của A thì tôi phải thực hiện truy vấn 100 lần. Cảm ơn – Wasim

+0

Wasim, thêm .select_related ('a') vào xu hướng truy vấn của bạn –

+0

Cảm ơn bạn rất nhiều, nó hoạt động. Lưu ý: nếu tôi viết B.objects.filter (a__in = A.objects.filter (giá__lt = 10, weight__gt = 20) .query, c_d = F ('d')). Nó ném một lỗi SQL Error: Operand nên chứa 1 cột (s). Tôi đã xem SQL được tạo ra, sau đó thay vì .query tôi đã thay thế nó bằng .all và điều này giải quyết được vấn đề. Cảm ơn bạn lần nữa. – Wasim

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