【问题标题】:Django groups and permissionsDjango 组和权限
【发布时间】:2016-07-10 17:17:10
【问题描述】:

我想创建 2 个组(教授、学生)。我想限制学生创建和删除课程。

views.py:

def is_professor(function=None):

    def _is_professor(u):
      if user.groups.filter(name='Professor').exists():
          return True
      else:
          raise HttpResponseForbidden
  return _is_professor(function)

class ListCourseView(ListView):

    model = Course
    template_name = 'course_list.html'
    fields = '__all__'

@is_professor
class CreateCourseView(CreateView):

    def get_queryset(self, request):
        if not request.user.is_superuser:
             return False

    model = Course
    template_name = 'course/edit_course.html'
    fields = '__all__'

    def get_success_url(self):
        return reverse('courses-list')

    def get_context_data(self, **kwargs):

         context = super(CreateCourseView, self).get_context_data(**kwargs)
        context['action'] = reverse('courses-new')

        return context

class UpdateCourseView(UpdateView):

    model = Course
    template_name = 'course/edit_course.html'
    fields = '__all__'

    def get_success_url(self):
        return reverse('courses-list')

def get_context_data(self, **kwargs):

    context = super(UpdateCourseView, self).get_context_data(**kwargs)
    context['action'] = reverse('courses-edit',
                                kwargs={'pk': self.get_object().id})

    return context

class DeleteCourseView(DeleteView):

    model = Course
    template_name = 'course/delete_course.html'

    def get_success_url(self):
        return reverse('courses-list')

models.py

 class Course(models.Model):
    name = models.CharField(
    max_length=255,
    )

    def __str__(self):
        return ' '.join([
        self.name
        ])



class UserProfile(models.Model):
    user = models.OneToOneField(User)

    picture = models.ImageField(upload_to='profile_images', blank=True)

    class Meta:
        permissions = ( ('add_course', 'Add course'), )

    def __unicode__(self):
        return self.user.username

这是我尝试过的。首先我得到一个错误

NameError:未定义全局名称“用户”。

其次,我仍然认为这行不通:)

【问题讨论】:

    标签: python django permissions decorator


    【解决方案1】:

    我认为第一个错误是因为这里没有定义用户

    def is_professor(function=None):
    
        def _is_professor(u):
          if user.groups.filter(name='Professor').exists():
              return True
          else:
              raise HttpResponseForbidden
      return _is_professor(function)
    

    在函数_is_professor(u)中应该是request.user

    【讨论】:

    • 当我将 'u' 更改为 'user' 时出现新错误:AttributeError: type object 'CreateCourseView' has no attribute 'groups' 我尝试在 /admin 页面上添加组,但似乎没有正在工作..
    • 如果我这样写: def _is_professor(request): user = request.user if user.groups.filter(name='Professor').exists(): return True else: raise HttpResponseForbidden return _is_professor(function) AttributeError: type object 'CreateCourseView' has no attribute 'user' 。我认为问题出在models.py 我需要创建组或smthing ..
    【解决方案2】:

    我为我的 django 项目之一做的事情是:

    我定义了一个检查权限以及用户是否通过身份验证的函数:

    from django.contrib.auth.decorators import user_passes_test
    
    def group_required(*group_names):
        """Requires user membership in at least one of the groups passed in."""
        def in_groups(u):
            if u.is_authenticated():
                if bool(u.groups.filter(name__in=group_names)) | u.is_superuser:
                    return True
            return False
    
        return user_passes_test(in_groups, login_url='403')
    

    然后我通过这个函数作为我的函数的装饰器:

    from whatever import group_required
    
    @group_required('Professor')
    def action_only_for_professor(request):
        # do things
    
    @group_required('Student')
    def action_only_for_student(request):
        # do other things
    

    使用此方法,您可以像这样为您的函数声明多组:

    @group_required('Professor', 'Student', 'Administrator', ...)
    

    此技巧仅适用于您创建的方法。 如果你想在课堂上做同样的事情,我建议你检查 django-braces (e.q. http://django-braces.readthedocs.org/en/latest/index.html)。 Django 大括号的工作原理是这样的:

    from braces.views import GroupRequiredMixin
    
    class CreateCourseView(CreateView, GroupRequiredMixin):
        group_required = u"Professor"
    
        def get_queryset(self, request):
            if not request.user.is_superuser:
                 return False
    
        model = Course
        template_name = 'course/edit_course.html'
        fields = '__all__'
    
        def get_success_url(self):
            return reverse('courses-list')
    
        def get_context_data(self, **kwargs):
    
             context = super(CreateCourseView, self).get_context_data(**kwargs)
            context['action'] = reverse('courses-new')
    
            return context
    

    如果您想在课堂上使用多个组权限,只需这样做:

    group_required = [u"Professor", u"Student", u"Administrator", etc...]
    

    Django-braces 在检查你的类的权限方面非常强大,从某种意义上说,你可以检查用户是否经过身份验证(使用 LoginRequiredMixin)、是否匿名(AnonymousrequiredMixin)、是否是超级用户(SuperuserRequiredMixin)、是否获得了一个(PermissionRequiredMixin)或多个权限(MultiplePermissionRequiredMixin),以及越来越多的东西!你只需要使用你想使用的适当的 mixin 来继承你的类;)

    希望它会有所帮助,并等待你的回报:)

    【讨论】:

    • 哦,我忘了,要使用 group_required 装饰器,或者 django 大括号 mixin,你必须在你的 django 项目中创建不同的组,显然 :)
    • 我仍然可以使用第二种方式(大括号)为所有用户创建课程...为什么 group_name 前面有“u”?
    • 我不确定,在 django-braces 上没有这样的信息,但是对于 python,它应该将字符串视为 unicode,即 group_name 前面的 u 的兴趣。
    • 这样可以创建群组吗?教授 = Group(name='Professors') ContentType.objects.get(app_label='course', model='course') can_view = Permission(name='Can View', codename='can_view_something', content_type=somemodel_ct) can_modify = Permission(name='Can Modify', codename='can_modify_something', content_type=somemodel_ct) can_create = Permission(name='Can Create', codename='can_create_something', content_type=somemodel_ct) 当我进入 /admin 页面时,我看到教授组,但没有选定的权限
    • 在您的管理员中,您可以管理您的用户权限,如果您想专门为用户添加一个/多个权限,您可以,或者您可以向组添加权限并将用户分配给该组。我更喜欢第二种方式(但这是个人的)。您也可以决定从您的 /admin 中创建组,或者您可以通过编程方式创建它们,我请您参考此页面以了解如何:[docs.djangoproject.com/en/1.9/topics/auth/default/…
    猜你喜欢
    • 2022-01-23
    • 2012-10-05
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 2019-04-25
    相关资源
    最近更新 更多