Поиск django-объектов, помеченных всеми тегами в наборе

В моем django-проекте есть функция поиска, где можно указать теги, например "яблоко, банан" и по этому запросу найти объекты определенной модели, помеченные тегами taggit. Когда я делаю:

tag_set = Tag.objects.filter(Q(name__in=tag_list))
query_set = Model.objects.filter(Q(tags__in=tag_set))

это дает мне объекты, помеченные либо "яблоком", либо "бананом". Но мне нужен оператор AND... Я попробовал:

query_set = Model.objects.filter(reduce(operator.and_, (Q(tags__in=x) for x in tag_set)))

но затем я получаю 'Tag' object is not iterable. Есть помощь?

Вы можете работать с:

queryset = Model.objects.all()
for tag in tag_list:
    queryset = queryset.filter(tags__name=tag)

Это сделает JOIN для каждого тега, и таким образом в конечном итоге queryset будет содержать только Model элементы, которые имеют все необходимые теги.

Другой подход заключается в подсчете количества совпавших тегов, так:

from django.db.models import Count

tag_set = set(tag_list)
Model.objects.filter(tag__name__in=tag_set).alias(
    ntags=Count('tags')
).filter(ntags=len(tag_set))
Вернуться на верх