Django filter many-to-many with contains


Question

I am trying to filter a bunch of objects through a many-to-many relation. Because the trigger_roles field may contain multiple entries I tried the contains filter. But as that is designed to be used with strings I'm pretty much helpless how i should filter this relation (you can ignore the values_list() atm.).

This function is attached to the user profile:

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)

My workflow model looks like this (simplified):

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)

Though the solution might be quiet simple, my brain won't tell me.

Thanks for your help.

1
66
12/22/2010 12:03:26 PM

Accepted Answer

Have you tried something like this:

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

or just if self.role.id is not a list of pks:

module.workflow_set.filter(trigger_roles__id__exact=self.role.id, allowed=True)
88
8/3/2015 3:25:01 AM

The simplest approach to achieve this would be checking for equalty over the whole instance (instead of the id) in the ManyToManyField. That looks if the instance is inside the many to many relationship. Example:

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

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon