Django视图delete函数如何实现仅作者可删的防御性编程
重构方案(零额外依赖,直接落地)
你当前代码的核心问题是完全没有后端权限校验逻辑,前端的权限控制可以被任意绕过(比如用户直接手动输入删除URL、构造简单POST请求就能删除任意食谱),按照防御性编程要求,所有权限判断必须在后端业务逻辑层执行。
前置确认
请先确认你的Recipe模型存在关联用户的外键字段(常规命名为author,存储食谱的创建者信息),如果你的字段名是creator/owner等,替换后续代码里的对应字段名即可。
重构后代码
首先在视图文件顶部导入需要的依赖:
from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_POST from django.http import HttpResponseForbidden from .models import Recipe
替换原有的删除视图:
@login_required @require_POST def delete_recipe(request, slug): """ 食谱删除视图:仅作者本人可执行删除 """ # 按slug查询食谱,不存在则直接返回404,避免服务器500错误 recipe = get_object_or_404(Recipe, slug=slug) # 核心权限校验:当前登录用户不是食谱作者时,直接返回403禁止操作 if recipe.author != request.user: return HttpResponseForbidden("你无权删除该食谱") # 所有校验通过后才执行删除逻辑 recipe.delete() return redirect('home')
配套调整
- 前端模板里的删除入口不能再用普通
<a>标签发GET请求,要改成POST表单,同时保留前端的显示判断(仅用于优化体验,不做权限依据):
{% if user.is_authenticated and recipe.author == user %} <form action="{% url 'delete_recipe' slug=recipe.slug %}" method="POST" onsubmit="return confirm('确认删除该食谱?操作不可恢复');"> {% csrf_token %} <button type="submit" class="btn btn-danger">删除食谱</button> </form> {% endif %}
- 用到的工具/装饰器作用说明:
@login_required:未登录用户访问该接口时自动跳转到登录页,从入口层拦截无登录态的请求@require_POST:限制接口仅接受POST请求,避免爬虫、误点链接触发删除操作get_object_or_404:替代原生Recipe.objects.get(),查询不到数据时返回标准404响应,避免抛出500服务错误
内容的提问来源于stack exchange,提问作者Erik Andersson
相关产品推荐
相关产品推荐

