Django组和权限

时间:2016-03-23 12:07:02

标签: python django permissions decorator

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

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:未定义全局名称“user”。

其次,我仍然认为这不会起作用。)

2 个答案:

答案 0 :(得分: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 Braces的工作原理如下:

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继承你的类;)

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

答案 1 :(得分:0)

我认为第一个错误是因为此处未定义用户

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