Получение объектов через отношение ManyToMany после фильтра в Django - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть эти модели:

class Notebook(models.Model):
    title = models.CharField(max_length=200)

class Tag(models.Model):
    name = models.CharField(max_length=63)
    notebooks = models.ManyToManyField(Notebook, related_name='tags')

, и я пытаюсь найти все ноутбуки, которые имеют два конкретных тега (я могу вывести остальную часть запроса, если смогу заставить работать два тега)

Я определяю запрос для двух тегов с помощью:

            query = Q(name__iexact='dna') | Q(name__iexact='notebook') 

и могу отфильтровать соответствующие теги с помощью:

Tag.objects.filter(query)

Но я ищу все записные книжки, которые имеют эти теги. В SQL я бы сделал JOIN, но метод ORM select_related явно не работает с ManyToManyField

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

При охвате многозначных отношений документация гласит:

Последовательные вызовы filter () дополнительно ограничивают набор объектов, но для многозначных отношений , они применяются к любому объекту, связанному с основной моделью, не обязательно к тем объектам, которые были выбраны более ранним вызовом filter ().

В следующих примерах filter объединяется в цепочку, когда запрашивая отношения м2м. Таким образом, основываясь на моделях, перечисленных в вопросе, вы можете создать запрос и затем l oop через теги, чтобы продолжать добавлять .filter(tags_name__iexact=tag) к объекту запроса

        tags = ['dna', 'notebook']
        q = Notebook.objects
        for tag in tags:
            q = q.filter(tags__name__iexact=tag)
        return q

. Сначала я думал, что такой подход будет включает в себя создание большого объекта Q с уменьшением лямбы, но с цепочкой.

0 голосов
/ 27 февраля 2020

Вы можете фильтровать, используя related_name:

Notebook.objects.filter(Q(tags__name__iexact='dna') | Q(tags__name__iexact='notebook'))

ИЛИ

tags = ['dna', 'notebook']
Notebook.objects.filter(tags__name__in=tags)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...