5

Django 和编程菜鸟在这里。我已经制作了一个我想部署的应用程序,但我需要弄清楚如何将 UpdateView 的访问权限限制为该对象的创建者,我很困惑。

目前,用户可以使用 CreateView .../universities/create/ 创建大学对象,但随后任何用户都可以使用 .../universities/update/ 编辑该对象。我想对此进行配置,以便只有该大学的创建者用户(具有 ManytoMany 属性“管理员”的任何用户)才能访问其大学对象的 UpdateView。

任何意见,将不胜感激。我在这上面花了几天时间,但并没有太大的吸引力……感谢您的阅读。

模型.py

class University(models.Model):
    name = models.CharField(max_length=100)
    about = models.TextField()
    administrators = models.ManyToManyField(User)
    profile_picture = models.FileField(upload_to=get_upload_file_name, blank=True)

    def __unicode__(self):
        return unicode(self.name)

    def get_absolute_url(self):
        return reverse('university_detail', kwargs={'pk': str(self.id)})

视图.py

class UniversityCreateView(CreateView):
    model = University
    form_class = UniversityForm
    template_name = 'university_create.html'

    def form_valid(self, form):
        f = form.save(commit=False)
        f.save()
        return super(UniversityCreateView, self).form_valid(form)

class UniversityUpdateView(UpdateView):
    model = University
    form_class = UniversityForm
    template_name='university_form.html'
4

3 回答 3

2

你必须在你的视图中包含权限装饰器,更多信息在这里https://docs.djangoproject.com/en/dev/topics/auth/https://docs.djangoproject.com/en/dev/topics/身份验证/默认/#topic-授权

因此,如果您想将 updateview 限制为具有 ManytoMany 属性“管理员”的任何用户,您必须执行以下操作:

视图.py

from appname.users.decorators import requiresGroup
from django.contrib.auth.decorators import login_required



class UniversityUpdateView(UpdateView):
    model = University
    form_class = UniversityForm
    template_name='university_form.html'

    @method_decorator(requiresGroup("groupname" , login_url='/accounts/login/'))
    def dispatch(self, request, *args, **kwargs):
    return super(UniversityUpdateView, self).dispatch(request, *args, **kwargs)

另外,如果您还没有,您必须在您的 models.py 的顶部包含以下内容

from django.contrib.auth.modes import user

虽然我假设它在那里,因为你已经用用户模型定义了你的管理员

然后转到 django admin 中的组设置(应该是 localhost/admin/auth/group 之类的 url,添加您的特殊管理员组名称,然后转到 admin 用户部分(localhost/admin/auth/user),然后制作确保他们已被放入管理员组

然后将 @requiresGroup 装饰器中的“groupname”替换为用户组的实际名称

@requiresGroup 装饰器不是标准装饰器,因此必须编写

创建一个文件夹路径和文件,如 appname/users.decorators.py 然后在 decorators.py 中写入

from functools import update_wrapper , wraps
from django.utils.decorators import available_attrs
from django.http import HttpResponse, HttpResponseRedirect


def requiresGroup(groupname):
    def decorator(view_function):
        def _wrapped_view(request,*args,**kwargs):
            if request.user.groups.filter(name=groupname).count()!=1:
                return HttpResponseRedirect("/")
            else:
                return view_function(request,*args,**kwargs)
        return wraps(view_function,assigned=available_attrs(view_function))(_wrapped_view)
    return decorator

希望这有帮助

编辑:犯了一个错误,把装饰器放在类上面,它们应该在类内部的一个函数中,几乎立即注意到我的错误所以希望我没有造成任何麻烦

于 2013-08-29T09:32:13.570 回答
2

You can use UserPassesTestMixin as the documentation says:

limit access based on certain permissions or some other test

just implement test_func(self) that returns True if the user should enter the view.

You might write a code like this:

class UniversityUpdateView(UserPassesTestMixin,UpdateView):
    def test_func(self):
        return self.request.user.administrators_set.filter(pk=self.get_object().pk).exists()
    model = University
    form_class = UniversityForm
    template_name='university_form.html'
于 2018-01-26T18:51:30.800 回答
0

您可以覆盖get基于类的视图的方法(在这种情况下UniversityUpdateView)。然后在方法中检查用户是否有权访问该页面,如果没有引发异常或将用户重定向到另一个页面。如果用户有足够的权限访问该页面,那么就让正常行为继续下去。

class UniversityUpdateView(UpdateView):
    model = University
    form_class = UniversityForm
    template_name='university_form.html'

    def get(self, request, *args, **kwargs):
        if request.user.groups.filter(name=groupname).count()!=1:
                return HttpResponseRedirect("/")
        return super().get(request, *args, **kwargs)
于 2020-04-20T08:29:50.603 回答