我有一个视图,我想验证用户编辑/删除帖子的权限。它应该检查发出请求的用户是否是创建帖子的用户。
下面是我用几种不同方法解决这个问题的观点,我用mixin,一个装饰器和一个通用函数编写了一个基于类的视图。
我很困惑哪个是最好的做法。一方面我觉得基于类的视图对此有点过分并最终会使代码变得不那么清晰,我也不喜欢装饰器将进行3次函数调用,而不是我可以使用check_function进行的一次调用。
应该注意我计划在具有类似结构的其他模型上使用此解决方案。
感谢任何帮助和建议,谢谢!
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404, redirect
from django.core.exceptions import PermissionDenied
from django.contrib.auth.decorators import login_required
from .models import Post
from .forms import PostForm
'''
def verify_author(func):
def check_and_call(request, *args, **kwargs):
id = kwargs["id"]
instance = get_object_or_404(model, id=id)
if request.user == instance.author:
return func(request, *args, **kwargs)
else:
raise PermissionDenied
return check_and_call
'''
def check_author(request, *args, **kwargs):
instance = kwargs['instance']
if not request.user == instance.author:
raise PermissionDenied
'''
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import UpdateView, DeleteView
class IsAuthorMixin(object):
def get_object(self, *args, **kwargs):
instance = super(IsAuthorMixin, self).get_object(*args, **kwargs)
if not instance.author == self.request.user:
raise PermissionDenied # 403, might be changed to 404
return instance
class PostUpdateView(IsAuthorMixin, LoginRequiredMixin, UpdateView):
model = Post
form_class = PostForm
template_name = 'Post_form.html'
class JobDeleteView(LoginRequiredMixin, IsAuthorMixin, DeleteView):
model = Post
success_url = '/'
'''
@login_required
@verify_author
def post_update(request, id):
instance = get_object_or_404(Post, id=id)
check_author(request, instance=instance)
form = PostForm(request.POST or None, request.FILES or None, instance=instance)
if form.is_valid():
instance= form.save(commit=False)
instance.save()
return HttpResponseRedirect(instance.get_abs_url())
context = {"form": form,}
return render(request, "post_form.html", context)
@login_required
@verify_author
def post_destroy(request, id):
instance = get_object_or_404(Post, id=id)
check_author(request, instance=instance)
instance.delete()
return redirect("posts:list")