【问题标题】:In Django, how do I check if a user is in a certain group?在 Django 中,如何检查用户是否在某个组中?
【发布时间】:2011-06-14 21:53:35
【问题描述】:

我在 Django 的管理站点中创建了一个自定义组。

在我的代码中,我想检查用户是否在该组中。我该怎么做?

【问题讨论】:

    标签: python django django-authentication


    【解决方案1】:

    您可以通过User 上的groups 属性访问这些组。

    from django.contrib.auth.models import User, Group
    
    group = Group(name = "Editor")
    group.save()                    # save this new group for this example
    user = User.objects.get(pk = 1) # assuming, there is one initial user 
    user.groups.add(group)          # user is now in the "Editor" group
    

    然后user.groups.all() 返回[<Group: Editor>]

    或者,更直接地,您可以通过以下方式检查用户是否在组中:

    if django_user.groups.filter(name = groupname).exists():
    
        ...
    

    请注意,groupname也可以是实际的 Django Group 对象。

    【讨论】:

    • 实际检查是if user.groups.filter(name=group_name).count(): # do something
    • 或使用 .exists() 代替 .count()
    • 问题是关于查询用户模型的所属组,而不是如何实例化它们... -.-
    【解决方案2】:

    如果您需要组中的用户列表,您可以这样做:

    from django.contrib.auth.models import Group
    users_in_group = Group.objects.get(name="group name").user_set.all()
    

    然后检查

     if user in users_in_group:
         # do something
    

    检查用户是否在组中。

    【讨论】:

    • 这对于用户数量不多的网站来说不能很好地扩展,因为它每次运行时都会将大量的用户表子集加载到内存中。
    • user.groups.filter(name="group name").exists() 应该可以正常工作。您编写的解决方案使用两个查询,因此不是很理想。
    • 正如它所说,“如果您需要组中的用户列表”...
    【解决方案3】:

    以防万一您想检查用户的组是否属于预定义的组列表:

    def is_allowed(user):
        allowed_group = set(['admin', 'lead', 'manager'])
        usr = User.objects.get(username=user)
        groups = [ x.name for x in usr.groups.all()]
        if allowed_group.intersection(set(groups)):
           return True
        return False
    
    【解决方案4】:

    您的 User 对象通过 ManyToMany 关系链接到 Group 对象。

    因此,您可以将 filter 方法应用于 user.groups

    因此,要检查给定用户是否在某个组中(例如“成员”),只需执行以下操作:

    def is_member(user):
        return user.groups.filter(name='Member').exists()
    

    如果您想检查给定用户是否属于多个给定组,请使用 __in 运算符,如下所示:

    def is_in_multiple_groups(user):
        return user.groups.filter(name__in=['group1', 'group2']).exists()
    

    请注意,这些函数可以与 @user_passes_test 装饰器一起使用来管理对视图的访问:

    from django.contrib.auth.decorators import login_required, user_passes_test
    @login_required
    @user_passes_test(is_member) # or @user_passes_test(is_in_multiple_groups)
    def myview(request):
        # Do your processing
    

    希望有帮助

    【讨论】:

    • 我不确定 django 数据库访问的内部工作原理,但这似乎比其他一些建议更有效,比如让所有用户组成一个组并执行标准 python @ 987654325@(反之亦然)。
    • 您不必在末尾添加.exists() 以返回布尔值吗?否则is_member()is_in_multiple_groups() 将返回QuerySet,这可能不会给出预期的结果。
    • 根据 Django 的文档,使用 exists() 确实更快,因为它不评估查询集:docs.djangoproject.com/en/dev/ref/models/querysets/#exists
    • 您可能希望超级用户通过测试(不查询数据库):def is_member(user): return user.is_superuser or user.groups.filter(...
    • is_in_multiple_groups 可以更明确地命名为is_in_some_groups,因为它不需要用户是所有组的成员
    【解决方案5】:

    一行:

    'Groupname' in user.groups.values_list('name', flat=True)
    

    计算结果为TrueFalse

    【讨论】:

    • 这是低效的,因为它会获取更多数据,然后在 django 端对其进行操作。最好使用.exists() 让数据库完成工作。
    【解决方案6】:

    你只需要一行:

    from django.contrib.auth.decorators import user_passes_test  
    
    @user_passes_test(lambda u: u.groups.filter(name='companyGroup').exists())
    def you_view():
        return HttpResponse("Since you're logged in, you can see this text!")
    

    【讨论】:

    • 虽然代码不是很干净,也不是很可重用,但是 +1 可以将它放在一行中。
    【解决方案7】:

    如果您不需要站点上的用户实例(就像我一样),您可以使用

    User.objects.filter(pk=userId, groups__name='Editor').exists()
    

    这将只产生一个对数据库的请求并返回一个布尔值。

    【讨论】:

      【解决方案8】:

      用户是否属于某个组,可以在django模板中使用:

      {% if group in request.user.groups.all %} "some action" {% endif %}

      【讨论】:

      • 这对我不起作用,似乎需要将组与组名进行比较
      【解决方案9】:

      我已经按照以下方式完成了。似乎效率低下,但我没有其他办法:

      @login_required
      def list_track(request):
      
      usergroup = request.user.groups.values_list('name', flat=True).first()
      if usergroup in 'appAdmin':
          tracks = QuestionTrack.objects.order_by('pk')
          return render(request, 'cmit/appadmin/list_track.html', {'tracks': tracks})
      
      else:
          return HttpResponseRedirect('/cmit/loggedin')
      

      【讨论】:

        【解决方案10】:

        User.objects.filter(username='tom', groups__name='admin').exists()

        该查询将通知您用户:“tom”是否属于组“admin”

        【讨论】:

        • groups__name 带双下划线
        【解决方案11】:

        我是这样做的。对于名为 Editor 的组。

        # views.py
        def index(request):
            current_user_groups = request.user.groups.values_list("name", flat=True)
            context = {
                "is_editor": "Editor" in current_user_groups,
            }
            return render(request, "index.html", context)
        

        模板

        # index.html
        {% if is_editor %}
          <h1>Editor tools</h1>
        {% endif %}
        

        【讨论】:

          【解决方案12】:

          我有类似的情况,我想测试用户是否在某个组中。因此,我创建了新文件 utils.py,我在其中放置了所有帮助我完成整个应用程序的小实用程序。在那里,我有这个定义:

          utils.py
          
          def is_company_admin(user):
              return user.groups.filter(name='company_admin').exists()
          

          所以基本上我正在测试用户是否在组 company_admin 中,为了清楚起见,我将此函数称为 is_company_admin

          当我想检查用户是否在 company_admin 中时,我只是这样做:

          views.py
          
          from .utils import *
          
          if is_company_admin(request.user):
                  data = Company.objects.all().filter(id=request.user.company.id)
          

          现在,如果您想在模板中进行测试,可以在上下文中添加 is_user_admin,如下所示:

          views.py
          
          return render(request, 'admin/users.html', {'data': data, 'is_company_admin': is_company_admin(request.user)})
          

          现在您可以在模板中评估您的响应:

          users.html
          
          {% if is_company_admin %}
               ... do something ...
          {% endif %}
          
          

          简单而干净的解决方案,基于可以在该线程前面找到的答案,但以不同的方式完成。希望它会对某人有所帮助。

          在 Django 3.0.4 中测试。

          【讨论】:

          • 在您的data = Company.objects.all().filter(id=request.user.company.id) 中,公司表示什么?那是你的模特吗?
          • 是的@hayden,在这种情况下,公司是我的模型。
          【解决方案13】:

          使用这个:

          {% for group in request.user.groups.all %}
              {% if group.name == 'GroupName' %}
              {% endif %}
          {% endfor %}
          

          【讨论】:

            猜你喜欢
            • 2016-04-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-22
            • 1970-01-01
            • 2016-05-29
            • 1970-01-01
            相关资源
            最近更新 更多