Django:如何过滤属于特定组的用户

44 投票
2 回答
50633 浏览
提问于 2025-04-15 16:28

我想要把一个表单字段的查询结果缩小到用户所属的组。这个字段是和用户表有外键关联的。

这些组是我之前设置好的。我的模型可能长得像这样:

myuser = models.ForeignKey(User)

而我的ModelForm非常简单:

class MyForm(ModelForm):
    class Meta:
        model = MyModel

所以当我在views.py中创建这个表单时,我会这样做:

form = MyForm()

现在我的问题是,怎么才能把myuser字段过滤一下,只显示属于'foo'组的用户呢,类似这样:

form.fields["myuser"].queryset = ???

在SQL中查询看起来是这样的:

mysql> SELECT * from auth_user INNER JOIN auth_user_groups ON auth_user.id = auth_user_groups.user_id INNER JOIN auth_group ON auth_group.id = auth_user_groups.group_id WHERE auth_group.name = 'client';

不过我想避免使用原始的SQL语句。这样做有可能吗?

2 个回答

31

这是一个很老的问题,但对于那些像我一样在网上搜索答案的人来说,请注意,之前的答案现在已经不完全正确了。一个用户可以属于多个组,所以要正确检查一个用户是否在某个组里,你应该这样做:

qs = User.objects.filter(groups__name__in=['foo'])

当然,如果你想检查多个组,可以把这些组添加到列表里:

qs = User.objects.filter(groups__name__in=['foo', 'bar'])
67

你需要使用Django在跨关系查询时的约定,来在你的查询集中连接到组表。

首先,我建议给你的关系起个related_name。这样写出来的代码比Django默认生成的要更容易理解。

class Group(models.Model):
    myuser = models.ForeignKey(User, related_name='groups')

如果你只想要一个特定的组,你可以通过这个关系进行连接,并使用以下任一方法来比较名称字段:

form.fields['myuser'].queryset = User.objects.filter(
    groups__name='foo')
form.fields['myuser'].queryset = User.objects.filter(
    groups__name__in=['foo'])

如果你想要筛选多个组,可以使用in条件:

form.fields['myuser'].queryset = User.objects.filter(
    groups__name__in=['foo', 'bar'])

如果你想快速查看生成的SQL语句,可以这样做:

qs = User.objects.filter(groups__name='foo')
print qs.query 

撰写回答