Подтвердить что ты не робот

Django queryset получает точный многотонный поиск

У меня есть pk список экземпляров модели Tag, скажем

pk_list = [10, 6, 3]

У меня есть еще одна модель с тегом m2m тегов и экземпляр, который содержит ровно 3 тега (выше pks).

class Node(models.Model):
    ...
    tags = models.ManyToManyField(Tag, related_name='nodes')

Я хотел бы получить Node, который содержит точный набор тегов, как указано в моем pk_list. Когда я делаю

Node.objects.filter(tags__in=pk_list)

он возвращает список из трех одинаковых экземпляров

[<Node: My node title>, <Node: My node title>, <Node: My node title>]

Вызов .get() не работает, потому что он должен возвращать один экземпляр, очевидно.

Итак, как я могу получить один экземпляр? Я должен отметить, что если мой pk_list был другим, например. [10, 6] или [10, 6, 3, 7], тогда я ничего не должен получать. Мне нужно точное соответствие.

Спасибо

4b9b3361

Ответ 1

Один подход заключается в использовании цепочки фильтров:

node_query = Node.objects.all()
pk_list = [10, 6, 3]

for pk in pk_list:
    node_query = node_query.filter(tags=pk)

Теперь node_query будет соответствовать node, у которого не менее три тега с pk 10, 6, 3. Для точного сопоставления трех тегов:

UPDATE: Благодаря @janos и @Adrián López правильный ответ:

from django.db.models import Count

pk_list = [10, 6, 3]
node_query = Node.objects.annotate(count=Count('tags')).filter(count=len(pk_list))

for pk in pk_list:
    node_query = node_query.filter(tags__pk=pk)