DRF函数视图@api_view如何返回POST请求默认内容
答案
完全可以实现,效果能和generics.CreateAPIView完全对齐。
原理说明
generics.CreateAPIView能在POST提交前渲染默认请求内容结构,核心靠两点逻辑:
- 视图绑定了序列化器类,DRF的可浏览API渲染器(BrowsableAPIRenderer)可以通过序列化器实例,自动生成符合字段定义的空请求体模板,填充到交互表单中
- 类视图对浏览器发起的GET请求做了兼容:哪怕视图本身只处理POST业务,只要是浏览器访问可浏览API页面,不会直接返回405错误,会放行请求用于渲染交互界面
@api_view装饰的函数视图默认没有上述兼容逻辑:如果只给装饰器传['POST'],浏览器发GET请求访问接口地址时,会在进入视图逻辑前就被拦截返回405,自然无法渲染表单结构。
具体实现方法
基础写法
直接给@api_view加上GET方法允许,在视图内分支处理请求即可:
from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status from .serializers import YourModelSerializer # 替换成你自己的序列化器 @api_view(['GET', 'POST']) def create_resource_view(request): if request.method == 'POST': # POST请求走正常的校验、存储逻辑,和你原有写法一致 serializer = YourModelSerializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) # GET请求返回空序列化器的默认结构,供可浏览API渲染表单 empty_serializer = YourModelSerializer() return Response(empty_serializer.data)
这个写法已经能实现和类视图一致的效果:浏览器访问接口地址时,会自动渲染带默认请求结构的POST提交表单。
完全对齐类视图行为的增强写法
如果需要和CreateAPIView行为完全一致——也就是非浏览器的JSON格式GET请求返回405,仅允许浏览器访问可浏览API时GET请求生效,可以加一层判断:
@api_view(['GET', 'POST']) def create_resource_view(request): if request.method == 'POST': serializer = YourModelSerializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) # 非浏览器发起的GET请求直接返回405 if 'text/html' not in request.META.get('HTTP_ACCEPT', ''): return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED) empty_serializer = YourModelSerializer() return Response(empty_serializer.data)
内容的提问来源于stack exchange,提问作者Khayal Farajov
相关产品推荐
相关产品推荐

