Django 如何将对象的UpdateView访问权限限制为该对象的创建者
这里是Django和编程noob。我已经制作了一个我想部署的应用程序,但是我需要弄清楚如何将对UpdateView的访问限制到该对象的创建者,我被难住了 目前,用户可以使用CreateView…/universions/create/创建大学对象,但任何用户都可以使用…/universions/update/编辑该对象。我想对此进行配置,以便只有该大学的创建者(任何具有ManytoMany属性“administrator”的用户)才能访问其大学对象的UpdateView 如有任何建议,将不胜感激。我花了几天的时间在这上面,但我没有取得太大的进展…谢谢阅读 型号.pyDjango 如何将对象的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 如有任何建议,将不胜感激
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至少看起来像我不久将需要的更新视图的另一个功能。我将继续尝试查看它是否解决了当前的权限问题。