【问题标题】:Django: How to filter Users that belong to a specific groupDjango:如何过滤属于特定组的用户
【发布时间】:2010-12-21 02:52:32
【问题描述】:

我希望将具有用户表外键的表单字段的查询集缩小到用户所属的组。

这些组之前已由我关联。该模型可能具有以下内容:

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。有可能吗?

【问题讨论】:

    标签: python django


    【解决方案1】:

    您需要使用Django's convention for joining across relationships 加入查询集中的组表。

    首先,我建议给你们的关系一个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 
    

    【讨论】:

    • 太棒了,谢谢乔。当您发布答案时,我在上面发布了 SQL。感谢反馈,效果很好。
    • 没有问题,我回过头来编辑它,向您展示如何打印出查询集的 SQL,以便您可以将其与您的预期进行比较。
    【解决方案2】:

    这是一个非常古老的问题,但对于那些在谷歌上搜索答案的人(就像我所做的那样),请知道接受的答案不再是 100% 正确的。一个用户可以属于多个组,因此要正确检查用户是否在某个组中,您应该这样做:

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

    当然,如果你想检查多个组,你可以将它们添加到列表中:

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

    【讨论】:

    • 我更新了我的答案以反映您对多个组的资格的担忧,但如果您试图限制为单个组,使用 '=' 而不是 'in' 并没有错。
    • 第二次@JoeHolloway 在这里。在查询单个组中的用户时,User.objects.filter(groups__name='foo') 格式工作得非常好。
    猜你喜欢
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2019-01-04
    • 2019-08-10
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多