Django Manytomy过滤器()

Django Manytomy过滤器(),django,django-models,Django,Django Models,我有一个模型: class Zone(models.Model): name = models.CharField(max_length=128) users = models.ManyToManyField(User, related_name='zones', null=True, blank=True) 我需要沿着以下线路构造一个过滤器: u = User.objects.filter(...zones contains a particular zone...) 它必

我有一个模型:

class Zone(models.Model):
    name = models.CharField(max_length=128)
    users = models.ManyToManyField(User, related_name='zones', null=True, blank=True)
我需要沿着以下线路构造一个过滤器:

u = User.objects.filter(...zones contains a particular zone...)
它必须是用户的筛选器,并且必须是单个筛选器参数。原因是我正在构造URL查询字符串以过滤管理员用户变更列表:http://myserver/admin/auth/user/?zones=3


看起来应该很简单,但我的大脑不配合

只是重复托马斯兹说的话

在=。。。在和测试中设置过滤器的样式。以下是针对您的特定问题的语法:

users_in_1zone = User.objects.filter(zones__id=<id1>)
# same thing but using in
users_in_1zone = User.objects.filter(zones__in=[<id1>])

# filtering on a few zones, by id
users_in_zones = User.objects.filter(zones__in=[<id1>, <id2>, <id3>])
# and by zone object (object gets converted to pk under the covers)
users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3])

使用时,到处都会使用双下划线语法。

请注意,如果用户可能在查询中使用的多个区域中,您可能需要添加.distinct。否则,您将多次获得一个用户:

users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3]).distinct()

另一种方法是遍历中间表。我会在Django ORM中这样表达:

UserZone=User.zones.through 对于单个区域 用户\u在\u区域=User.objects.filter id\uuu in=UserZone.objects.filterzone=zone1.value'user' 对于多个区域 分区中的用户=User.objects.filter id\uuu-in=UserZone.objects.filterzone\uu-in=[zone1,zone2,zone3]。值为'user' 如果它不需要指定.value'user'就好了,但是Django 3.0.7版似乎需要它

上述代码最终将生成类似以下内容的SQL:

选择*从1,2,3中的用户位置id中选择用户位置id从1,2,3中的用户位置id中选择用户位置id
这很好,因为它没有任何可能导致返回重复用户的中间联接

我不确定是否正确-不是User.objects.filterzones\uuuu id=或User.objects.filterzones\uuuu in=对这很好吗?没关系:顺便说一句User.objects.filterzones\uu in=应该是User.objects.filterzones\uu id\uu in=只是想向谷歌上的任何人指出,只有设置了相关的名称,它才有效。例如,zone_set就不起作用。浪费了半个小时:-谢谢@maxm。更新了一些示例的最新链接。双下划线argh。你能说,如果我想让处于一组区域的用户,而不仅仅是其中任何一个区域的用户,该怎么办?让我们假设查找在zone1、zone3、…中的用户。。区域10在对几个区域进行过滤后,通过id查看示例中的…\u。在本例中,这些区域显示了对多个id/对象的过滤。只需传入您关心的zone1、zone3和zone10 ID/对象。或者根据需要添加第四个。Thx。我只是针对单个值进行筛选,而不是包含单个值的数组。这本身并不是一个答案。你应该添加一条评论或编辑QB的答案,而不是添加一个额外的部分答案。是的-如果你想编辑你的答案,那么它是完整的,除非你有足够的业力来编辑QB的答案?那么这将是最好的选择。理想情况下,在StackOverflow上有一个正确的答案。“通常情况下,效果并不是很好,但这是值得瞄准的。”安德贝克同意了!回想起来,QB的答案可能应该是对istruble答案的评论,而我认为我的答案足够清晰,可以单独给出答案,但啊,很好