我试图通过多对多关系过滤一堆对象。因为trigger_roles字段可能包含多个条目,所以我尝试了包含过滤器。但是因为它被设计为与字符串一起使用,我几乎无能为力地过滤这种关系(你可以忽略values_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)
虽然解决方案可能很简单,但我的大脑不会告诉我。
感谢您的帮助。
答案 0 :(得分:85)
你有没有试过这样的事情:
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 :(得分:14)
实现这一目标的最简单方法是检查ManyToManyField
中整个实例(而不是id)的相等性。这看起来实例是在多对多的关系中。例如:
module.workflow_set.filter(trigger_roles=self.role, allowed=True)
答案 2 :(得分:4)
奇点在第一个例子中几乎是正确的。你只需要确保它是一个列表。第二个例子,检查trigger_roles__id__exact
是一个更好的解决方案。
module.workflow_set.filter(trigger_roles__in=[self.role.id],allowed=True)