如何在Django类视图中有效使用PUT和DELETE HTTP方法?
Django类视图实现PUT/DELETE请求的CRUD方案
一、URL路由配置
按照需求映射URL规则,区分集合操作(列表/创建)和单个资源操作(详情/更新/删除):
在backendapp/urls.py中添加:
from django.urls import path from .views import CategoryView, CategoryDetailView urlpatterns = [ # 分类列表页 + 创建页 path('categories/', CategoryView.as_view(), name='category-list'), path('categories/create/', CategoryView.as_view(), name='category-create'), # 分类详情页 + 更新 + 删除 path('categories/<int:pk>/', CategoryDetailView.as_view(), name='category-detail'), ]
二、拆分视图类(职责更清晰)
将原CategoryView拆分为两个类,分别处理不同场景的请求:
1. 集合操作视图(列表+创建)
from django.shortcuts import render, redirect from django.views import View from .models import Category from .forms import CategoryForm # 需提前定义ModelForm class CategoryView(View): template_name = 'backendapp/pages/category/categories.html' def get(self, request): # 渲染分类列表+创建表单 categories = Category.objects.all() form = CategoryForm() return render(request, self.template_name, { 'categories': categories, 'form': form }) def post(self, request): # 处理创建分类的POST请求 form = CategoryForm(request.POST) if form.is_valid(): form.save() return redirect('category-list') # 验证失败,返回带错误的页面 categories = Category.objects.all() return render(request, self.template_name, { 'categories': categories, 'form': form })
2. 单个资源操作视图(详情+更新+删除)
from django.shortcuts import get_object_or_404, render, redirect from django.views import View from django.http import QueryDict from .models import Category from .forms import CategoryForm class CategoryDetailView(View): template_name = 'backendapp/pages/category/category_detail.html' def get(self, request, pk): # 渲染单个分类的详情+更新表单 category = get_object_or_404(Category, pk=pk) form = CategoryForm(instance=category) return render(request, self.template_name, { 'category': category, 'form': form }) def put(self, request, pk): # 处理更新分类的PUT请求 category = get_object_or_404(Category, pk=pk) # Django默认不解析PUT数据到request.POST,需手动解析body put_data = QueryDict(request.body) form = CategoryForm(put_data, instance=category) if form.is_valid(): form.save() return redirect('category-list') # 验证失败,返回详情页带错误 return render(request, self.template_name, { 'category': category, 'form': form }) def delete(self, request, pk): # 处理删除分类的DELETE请求 category = get_object_or_404(Category, pk=pk) category.delete() return redirect('category-list')
三、ModelForm定义(必填)
创建backendapp/forms.py,定义与Category模型绑定的表单:
from django.forms import ModelForm from .models import Category class CategoryForm(ModelForm): class Meta: model = Category fields = ['name'] # 替换为你的Category模型实际字段
四、前端提交PUT/DELETE请求的两种方式
浏览器原生表单仅支持GET/POST,需通过以下方式模拟PUT/DELETE:
1. 使用POST + _method参数(Django内置支持)
Django的CommonMiddleware会自动识别_method参数,将POST请求转换为对应HTTP方法:
删除按钮表单
<form action="{% url 'category-detail' category.pk %}" method="POST"> {% csrf_token %} <input type="hidden" name="_method" value="DELETE"> <button type="submit" onclick="return confirm('确定删除?')">删除分类</button> </form>
更新分类表单
<form action="{% url 'category-detail' category.pk %}" method="POST"> {% csrf_token %} <input type="hidden" name="_method" value="PUT"> {{ form.as_p }} <button type="submit">更新分类</button> </form>
2. AJAX异步请求
适合单页或异步场景,直接发送PUT/DELETE请求:
// 更新分类的AJAX示例 document.querySelector('#update-form').addEventListener('submit', function(e) { e.preventDefault(); const pk = this.dataset.pk; const formData = new FormData(this); fetch(`/backendapp/categories/${pk}/`, { method: 'PUT', headers: { 'X-CSRFToken': getCookie('csrftoken') // 必须携带CSRF令牌 }, body: formData }).then(res => { if (res.ok) location.href = '/backendapp/categories/'; else alert('更新失败'); }); }); // 获取CSRF令牌的工具函数 function getCookie(name) { let value = null; if (document.cookie) { const cookies = document.cookie.split(';'); for (let cookie of cookies) { const [key, val] = cookie.trim().split('='); if (key === name) value = decodeURIComponent(val); } } return value; }
五、关键注意事项
- 确保
django.middleware.common.CommonMiddleware和django.middleware.csrf.CsrfViewMiddleware在settings.py中间件列表中(默认已开启)。 - PUT请求的数据不会自动存入
request.POST,必须手动解析request.body。 - 使用
get_object_or_404自动处理主键不存在的情况,避免抛出异常。
内容的提问来源于stack exchange,提问作者user24265527
相关产品推荐
相关产品推荐

