2010-01-13 4 views
7

У меня есть эта структура модельных объектов:фильтр многие ко многим отношения в Django

Класс A:
b = models.ManyToManyField("B") 
Класс B:
c = models.ForeignKey("C") 
d = models.ForeignKey("D") 
Класс C:
d = models.ForeignKey("D") 

Это запрос, Я пытаюсь получить:
Я хочу получить все объекты B объекта A, а затем в каждом объекте B выполнить сравнение между объектом D и объектом cd ,

Я знаю, что просто перемещайтесь по коллекции B с помощью цикла и сделайте это сравнение. Но я нырнул на ManyToMany отношения, то я заметил, что я могу сделать следующее:

bObjects = A.objects.all().b 

q = bObjects.filter(c__d=None) 

Это работает, это дает мне все объекты с гр None г поля. Но когда я пытаюсь следующее:

q = bObjects.filter(c__d=d) 

Это дает мне не d определены, но d является объектом, как с в объекте B.

Что может быть проблема? Я буду рад, если вы предложите дальнейший путь для выполнения этой задачи. Обычно я пытаюсь написать свой запрос за одну операцию со многими и многими вспомогательными объектами и не используя циклы.

+1

всех эти а путают вы не мог бы выбрать лучшие имена: D? – maazza

ответ

6

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

Попробуйте это:

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

Что касается вопроса от вашего комментария ниже вы можете иметь 1 SQL запроса вместо 100 в этих способах:

1), если вы можете выразить свой выбор а из объектов в терминах запроса (например a.price < 10 и a.weight> 20) использовать эту функцию:

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

или это:

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

2), если у вас есть только список питон А объекты, используйте:

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

Спасибо, он работает. Еще один вопрос: если у меня есть список объектов основного объекта A. Могу ли я выполнить запрос, который вы написали с одной строкой, а не перебирать список A и делать то же самое. Просто я хочу сохранить хиты в DB id У меня есть 100 из A, тогда я должен сделать запрос 100 раз. Спасибо – Wasim

+0

Wasim, добавьте .select_related ('a') в запрос по вашему запросу –

+0

Спасибо, он работает. Замечание: если я пишу B.objects.filter (a__in = A.objects.filter (price__lt = 10, weight__gt = 20) .query, c_d = F ('d')). Он выдает ошибку SQL Error: Операнд должен содержать 1 столбец (столбцы). Я посмотрел на сгенерированный SQL, а вместо .query я заменил его на .all, и это решило проблему. Еще раз спасибо. – Wasim

Смежные вопросы