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

Фильтр Django много-ко-многим содержит

Я пытаюсь отфильтровать кучу объектов через отношение "многие ко многим". Поскольку поле trigger_roles может содержать несколько записей, я попробовал фильтр contains. Но поскольку это предназначено для использования со строками, я почти беспомощно, как я должен фильтровать это отношение (вы можете игнорировать value_list() atm.).

Эта функция прикрепляется к профилю пользователя:

def getVisiblePackages(self):
    visiblePackages = {}   
    for product in self.products.all():
        moduleDict = {}
        for module in product.module_set.all():
            pkgList = []
            involvedStatus = module.workflow_set.filter(trigger_roles__contains=self.role.id,allowed=True).values_list('current_state', flat=True)

Моя модель рабочего процесса выглядит так (упрощена):

class Workflow(models.Model):
    module = models.ForeignKey(Module)
    current_state = models.ForeignKey(Status)
    next_state = models.ForeignKey(Status)
    allowed = models.BooleanField(default=False)
    involved_roles = models.ManyToManyField(Role, blank=True, null=True)
    trigger_roles = models.ManyToManyField(Role, blank=True, null=True)

Хотя решение может быть спокойным простым, мой мозг не скажет мне.

Спасибо за вашу помощь.

4b9b3361

Ответ 1

Вы пробовали что-то вроде этого:

module.workflow_set.filter(trigger_roles__in=[self.role], allowed=True)

или просто, если self.role.id не является списком pks:

module.workflow_set.filter(trigger_roles__id__exact=self.role.id, allowed=True)

Ответ 2

Простейшим подходом для этого является проверка равенства по всему экземпляру (вместо id) в ManyToManyField. Это выглядит, если экземпляр внутри отношения "многие-многие". Пример:

module.workflow_set.filter(trigger_roles=self.role, allowed=True)

Ответ 3

сингулярность почти справа с первым примером. Вам просто нужно убедиться, что это список. Второй пример: проверка trigger_roles__id__exact является лучшим решением.

module.workflow_set.filter(trigger_roles__in=[self.role.id],allowed=True)

Ответ 4

Я знаю, что это старый вопрос, но похоже, что ОП никогда не получал ответа, который он искал. Если у вас есть два набора ManyToManyFields, которые вы хотите сравнить, трюк заключается в использовании оператора __in, а не contains. Например, если у вас есть модель "Событие" с ManyToMany для "Группы" в поле eventgroups, и ваша модель пользователя (очевидно) прикрепляется к группе, вы можете запросить вот так:

Event.objects.filter(eventgroups__in=u.groups.all())