2010-12-22 175 views
49

我想通过多对多关系过滤一堆对象。因为trigger_roles字段可能包含多个条目,所以我尝试了包含过滤器。但是,因为这是设计用于字符串我非常无奈,我应该如何过滤这个关系(你可以忽略values_list()atm。)。Django过滤器多对多包含

该功能安装到用户配置文件:

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) 

尽管解决方案可能是简单安静,我的大脑不会告诉我。

感谢您的帮助。

回答

66

你有没有尝试过这样的事情:

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) 
+1

不似乎工作。由于self.role.id只是一个int,而trigger_roles是它们的列表,所以我需要一个倒置的,就像我发现的那样,contains只包含字符串。 – 2010-12-22 11:24:53

4

奇点是第一个例子差不多吧。你只需要确保它是一个列表。第二个例子,检查trigger_roles__id__exact是一个更好的解决方案。

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

最简单的方法来实现,这将被检查equalty了在ManyToManyField整个实例(而不是ID)。这看起来实例是否在多对多关系中。例如:

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

我知道这是一个老问题,但它看起来像OP从来没有得到他所期待的答案。如果您想要比较两组ManyToManyFields,诀窍是使用__in运算符,而不是contains。因此,举例来说,如果你有一个“事件”模型与现场eventgroups一个多对多的“组”,和您的用户模型(显然)连接到组,您可以查询这样的:

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