Django 如何将对象的UpdateView访问权限限制为该对象的创建者

Django 如何将对象的UpdateView访问权限限制为该对象的创建者,django,django-models,django-views,django-permissions,Django,Django Models,Django Views,Django Permissions,这里是Django和编程noob。我已经制作了一个我想部署的应用程序,但是我需要弄清楚如何将对UpdateView的访问限制到该对象的创建者,我被难住了 目前,用户可以使用CreateView…/universions/create/创建大学对象,但任何用户都可以使用…/universions/update/编辑该对象。我想对此进行配置,以便只有该大学的创建者(任何具有ManytoMany属性“administrator”的用户)才能访问其大学对象的UpdateView 如有任何建议,将不胜感激

这里是Django和编程noob。我已经制作了一个我想部署的应用程序,但是我需要弄清楚如何将对UpdateView的访问限制到该对象的创建者,我被难住了

目前,用户可以使用CreateView…/universions/create/创建大学对象,但任何用户都可以使用…/universions/update/编辑该对象。我想对此进行配置,以便只有该大学的创建者(任何具有ManytoMany属性“administrator”的用户)才能访问其大学对象的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)})
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'
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)
视图.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)})
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'
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)

您必须在视图中包含权限装饰器,更多信息在这里,&

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

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'
视图.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)})
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'
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 user部分(localhost/admin/auth/user),然后确保它们已放入管理员组

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

@requiresGroup decorator不是标准的decorator,因此必须编写它

创建文件夹路径和文件,如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
希望这有帮助

编辑:犯了一个错误,将decorator放在类之上,它们应该在类中的一个函数中,几乎立即注意到我的错误,因此希望我没有造成任何问题

您可以使用文档中所述的:

基于某些权限或某些其他测试限制访问

只要实现
test\u func(self)
,如果用户应该进入视图,它将返回
True

您可以编写如下代码:

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'

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

class University更新视图(更新视图):
模型=大学
形式=大学形式
模板\u name='university\u form.html'
def get(自我、请求、*args、**kwargs):
if request.user.groups.filter(name=groupname).count()!=1:
返回HttpResponseRedirect(“/”)
return super().get(请求,*args,**kwargs)

可能重复的我看到这篇文章已被标记为重复,但我看不出这篇文章对我有什么帮助。我没有试图显示一个页面,用户可以在其中收到他们是管理员的大学列表。我试图阻止任何非大学管理员的人访问在大学里。如果我有误解,并且“可能重复”的链接确实为我提供了我需要的解决方案,我希望能解释一下它是如何工作的。这并没有被标记为重复的,我提出了这个建议,因为问其他问题的人似乎想要同样的东西(将UpdateView限制为登录用户创建的对象)。根据文档,在
UpdateView
中的
get_queryset
方法“返回用于检索此视图将显示的对象的queryset”。因此,如果您限制queryset的用户,其他用户创建的对象将不会显示。啊,好的,谢谢您的解释,get_queryset至少看起来像我不久将需要的更新视图的另一个功能。我将继续尝试查看它是否解决了当前的权限问题。