Django表单权限设置:仅允许创建者修改/删除自有实例(Generic UpdateView)
解决方案:给Django Generic UpdateView/DeleteView添加创建者权限控制
嘿,这个需求在Django开发里太常见了!要实现只有数据实例的创建者才能修改/删除,咱们可以基于Generic View的特性来搞,下面给你几个实用的方案:
方法一:使用UserPassesTestMixin(推荐,结构更清晰)
这个是Django自带的Mixin,专门用来做用户权限校验,代码逻辑一目了然:
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin from django.views.generic.edit import UpdateView, DeleteView from .models import YourModel # 替换成你的实际模型 class YourModelUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView): model = YourModel fields = ['title', 'content'] # 替换成你的表单字段 success_url = '/your-success-page/' # 替换成你的跳转地址 def test_func(self): # 获取当前要操作的实例 obj = self.get_object() # 校验当前登录用户是否是实例的创建者 return obj.created_by == self.request.user class YourModelDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): model = YourModel success_url = '/your-success-page/' def test_func(self): obj = self.get_object() return obj.created_by == self.request.user
注意:你的模型里得有一个关联用户的字段,比如
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="created_xxx"),用来记录谁创建了这个实例。
如果用户没有权限,默认会跳转到登录页;要是想自定义无权限提示,可以重写handle_no_permission方法:
def handle_no_permission(self): from django.http import HttpResponseForbidden return HttpResponseForbidden("抱歉,只有内容的创建者才能修改/删除它!")
方法二:重写get_object方法
另一种直接的方式是在View里重写get_object,在获取实例的环节就做权限拦截:
from django.views.generic.edit import UpdateView from django.http import HttpResponseForbidden from .models import YourModel class YourModelUpdateView(UpdateView): model = YourModel fields = ['title', 'content'] success_url = '/your-success-page/' def get_object(self, queryset=None): obj = super().get_object(queryset=queryset) # 校验权限,不满足直接返回403 if obj.created_by != self.request.user: return HttpResponseForbidden("你没有权限操作这个内容!") return obj
这个方法的好处是逻辑直接,在获取数据的第一步就完成校验。
方法三:自定义Mixin(适合多View复用)
如果你的项目里很多View都需要这个权限逻辑,不如封装成一个自定义Mixin,方便复用:
from django.contrib.auth.mixins import AccessMixin from django.http import HttpResponseForbidden class CreatorOnlyMixin(AccessMixin): def dispatch(self, request, *args, **kwargs): obj = self.get_object() if obj.created_by != request.user: return self.handle_no_permission() return super().dispatch(request, *args, **kwargs) def handle_no_permission(self): return HttpResponseForbidden("只有内容创建者才能执行此操作!")
之后在需要的View里直接继承这个Mixin即可:
class YourModelUpdateView(LoginRequiredMixin, CreatorOnlyMixin, UpdateView): model = YourModel fields = ['title', 'content'] success_url = '/your-success-page/'
最后提醒:记得给View加上LoginRequiredMixin,确保只有登录用户才能访问修改/删除页面哦!
内容的提问来源于stack exchange,提问作者Russell
相关产品推荐
相关产品推荐

