如何使用PUT/UPDATE/DELETE处理多字段?及多条件查询视图改写
我来帮你解决这两个问题,直接上干货:
1. 如何使用PUT、PATCH(UPDATE)、DELETE请求处理多字段操作?
这里需要区分不同请求的语义,针对性处理:
PUT请求(全量更新多字段):
PUT要求传递资源的所有必填字段(哪怕部分字段没有修改),用来完成全量更新。在DRF中,你需要将目标实例和请求数据传入序列化器,验证通过后保存即可。比如:serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data)这种方式会强制验证所有字段,确保资源的完整性。
PATCH请求(局部更新多字段):
如果只需要更新部分字段,用PATCH更合适(对应UPDATE场景)。DRF中只需在初始化序列化器时添加partial=True参数,这样就不需要传递所有必填字段,仅更新请求中提供的字段:serializer = SnippetSerializer(snippet, data=request.data, partial=True)DELETE请求(多字段条件删除):
先通过多字段组合查询到目标实例,再执行删除操作。要注意处理实例不存在的情况,返回404状态码。比如:try: snippet = Snippet.objects.get(name=request.data['name'], author=request.data['author']) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
2. Django REST Framework函数视图改写方案
要把原来通过pk获取实例改成name、id、author组合条件,需要修改路由配置和视图逻辑两部分,具体如下:
第一步:修改路由(urls.py)
把原来接收pk的路由,替换成接收三个参数的路由:
# 假设你的app名为snippets,根据实际情况调整 from django.urls import path from . import views urlpatterns = [ # 替换原来的pk路由 path('snippets/<str:name>/<int:id>/<str:author>/', views.snippet_detail), ]
注意参数类型要和你的Snippet模型字段类型匹配,比如如果author是外键(关联User模型),参数类型应该是<int:author>。
第二步:改写视图函数
from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from django.core.exceptions import MultipleObjectsReturned from .models import Snippet from .serializers import SnippetSerializer @api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, name, id, author): try: # 用name、id、author组合条件查询唯一实例 snippet = Snippet.objects.get(name=name, id=id, author=author) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) # 可选:如果三个字段组合可能返回多个实例,添加这个异常处理 except MultipleObjectsReturned: return Response( {"error": "Multiple snippets match the given criteria"}, status=status.HTTP_400_BAD_REQUEST ) if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
关键说明:
- 参数接收:视图函数的参数列表新增
name、id、author,和路由中的参数一一对应。 - 查询逻辑:把
Snippet.objects.get(pk=pk)改成多字段组合查询,确保能定位到目标实例。 - 异常补充:如果你的业务中这三个字段的组合不唯一,一定要捕获
MultipleObjectsReturned异常,避免服务器返回500错误。 - 局部更新支持(可选):如果需要支持PATCH请求,只需在
@api_view中添加'PATCH',然后新增分支:elif request.method == 'PATCH': serializer = SnippetSerializer(snippet, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
内容的提问来源于stack exchange,提问作者Loud JM
相关产品推荐
相关产品推荐

