Предположим, у меня есть следующие 3 модели, где каждая из двух моделей имеет отношение M2M к третьей модели.Django M2M Filter QuerySet с точным набором M2M
class FirstModel(models.Model):
third_model = models.ManyToMany('ThirdModel')
class SecondModel(models.Model):
third_model = models.ManyToMany('ThirdModel')
class ThirdModel(models.Model):
pass
Теперь предположим, что в дальнейшем у меня есть конкретный SecondModel
объект и FirstModel
QuerySet
. Мне нужно фильтровать QuerySet
так, что в результате QuerySet
содержит только FirstModel
объекты, которые имеют те же M2M
множество связей с ThirdModel
в M2M
отношениях SecondModel
объекта, установленных с ThirdModel
.
def some_filtering_method(first_model_qs, second_model):
third_models_set = second_model.third_model_set.all()
first_model_ids = list()
for third_model in third_models_set:
first_model_ids.append(
[first_model.pk
for first_model in third_model.first_model_set.all()])
intersection_of_first_model_ids = get_intersection(first_model_ids)
return first_model_qs.filter(pk__in=intersection_of_first_model_ids)
Есть ли более питонический способ сделать это в Django? Я пробовал следующее безрезультатно (после анализа необработанного запроса очевидно, почему это не сработает).
import operator
from django.db.models import Q
def some_filtering_method(first_model_qs, second_model):
return first_model_qs.filter(
reduce(
operator.and_,
(Q(third_model_set__contains=x)
for x in second_model.third_model_set.all())
)
)
Только для clarificat когда вы говорите «ваш код здесь», в каком коде вы ссылаетесь? Код 'some_filtering_method' в моем вопросе или какой-то пользовательский код, который нужно определить? – Rico