带post与user条件的Django DeleteView实现是否正确?
Django DeleteView 权限验证问题排查
我基于Django实现了一个带有post和user两个条件的DeleteView,其中user条件通过
self.object.user = self.request.user实现,post条件通过slug = self.kwargs['slug']实现(我怀疑这部分可能存在问题)。请问我的视图代码是否正确?我是Python新手,若有疏漏请见谅。视图代码如下:# Views.py class ProofDelete(LoginRequiredMixin, DeleteView): model = Proof def delete(self, *args, **kwargs): return super().delete(*args, **kwargs) def get_success_url(self, *args, **kwargs): sl...
嘿,作为新手能想到要做权限验证已经很棒了!不过你的代码目前还没正确实现这两个验证条件,我帮你拆解问题并给出修正方案:
问题点梳理
- 你提到的
self.object.user = self.request.user并没有出现在代码里,而且就算加上,这种写法是给对象赋值,不是验证当前用户是否有权限删除该对象; - 直接取
slug = self.kwargs['slug']只是拿到了URL参数,但没有把这个slug和用户权限关联起来,也没确保视图只处理这个slug对应的、属于当前用户的对象。
正确实现方案
Django的DeleteView默认会通过URL参数(slug/pk)获取对象,我们只需要重写get_object()方法,在里面添加权限校验即可,既保证slug匹配,又验证用户所有权。
修正后的完整代码如下:
from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import DeleteView from django.urls import reverse_lazy from django.core.exceptions import PermissionDenied from .models import Proof class ProofDelete(LoginRequiredMixin, DeleteView): model = Proof slug_field = "slug" # 替换成你Proof模型中存储slug的字段名 slug_url_kwarg = "slug" # 和你urls.py中定义的slug参数名保持一致 success_url = reverse_lazy("proof_list") # 替换成删除成功后跳转的页面名称 def get_object(self, queryset=None): # 先通过slug获取对应的对象 obj = super().get_object(queryset=queryset) # 验证当前用户是否是该对象的所有者 if obj.user != self.request.user: raise PermissionDenied("你没有权限删除这个内容") return obj
关键细节说明
slug_field&slug_url_kwarg:这两个属性让Django自动用URL里的slug参数匹配模型字段,不用你手动去解析self.kwargs,更规范;get_object():这是添加权限验证的最佳位置——先获取对象,再校验用户是否有权限,不满足就抛出403权限错误;- 冗余代码清理:你之前写的
delete()方法只是调用父类逻辑,完全可以删掉;如果get_success_url()没写完,直接用success_url属性指定跳转地址更简洁。
这样修改后,你的视图就会同时满足两个要求:
- 用户必须登录(
LoginRequiredMixin已处理); - 只能删除属于当前用户的、URL中slug对应的Proof对象。
内容的提问来源于stack exchange,提问作者Samir Tendulkar
相关产品推荐
相关产品推荐

