如何使用drf-yasg定义动态必填字段的自定义请求?
使用drf-yasg实现动态必填字段的请求校验与文档生成
要实现根据move_type值动态确定必填字段的请求,你可以结合DRF的Serializer和drf-yasg的Schema定义来完成,下面是具体步骤和代码示例:
1. 定义分场景的Serializer
先提取公共字段到基础Serializer,再为不同move_type定义各自的Serializer,明确对应场景的必填字段:
from rest_framework import serializers class BaseMoveSerializer(serializers.Serializer): move_type = serializers.CharField(required=True, choices=['P', 'D']) common_field = serializers.CharField(required=False) # 公共可选字段 # 当move_type为'P'时的Serializer class PMoveSerializer(BaseMoveSerializer): p_required_field1 = serializers.CharField(required=True) p_required_field2 = serializers.IntegerField(required=True) # 当move_type为'D'时的Serializer class DMoveSerializer(BaseMoveSerializer): d_required_field1 = serializers.CharField(required=True) d_required_field2 = serializers.DateTimeField(required=True)
2. 用drf-yasg定义动态请求文档
在视图中使用@swagger_auto_schema装饰器,通过oneOf关键字来描述不同move_type对应的请求结构,让Swagger文档能展示两种可选的请求格式:
from rest_framework.views import APIView from rest_framework.response import Response from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi class MoveOperationView(APIView): @swagger_auto_schema( request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['move_type'], oneOf=[ # move_type为'P'的请求结构 openapi.Schema( type=openapi.TYPE_OBJECT, required=['move_type', 'p_required_field1', 'p_required_field2'], properties={ 'move_type': openapi.Schema(type=openapi.TYPE_STRING, enum=['P']), 'p_required_field1': openapi.Schema(type=openapi.TYPE_STRING), 'p_required_field2': openapi.Schema(type=openapi.TYPE_INTEGER), 'common_field': openapi.Schema(type=openapi.TYPE_STRING), } ), # move_type为'D'的请求结构 openapi.Schema( type=openapi.TYPE_OBJECT, required=['move_type', 'd_required_field1', 'd_required_field2'], properties={ 'move_type': openapi.Schema(type=openapi.TYPE_STRING, enum=['D']), 'd_required_field1': openapi.Schema(type=openapi.TYPE_STRING), 'd_required_field2': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_DATETIME), 'common_field': openapi.Schema(type=openapi.TYPE_STRING), } ) ] ), responses={200: openapi.Response('操作成功')} ) def post(self, request): move_type = request.data.get('move_type') if not move_type: return Response({'error': 'move_type为必填字段'}, status=400) # 根据move_type选择对应的Serializer if move_type == 'P': serializer = PMoveSerializer(data=request.data) elif move_type == 'D': serializer = DMoveSerializer(data=request.data) else: return Response({'error': '无效的move_type值'}, status=400) # 执行校验并处理业务逻辑 if serializer.is_valid(): # 这里写你的业务处理代码 return Response(serializer.validated_data, status=200) return Response(serializer.errors, status=400)
关键说明
oneOf关键字:用来声明请求可以匹配多个Schema中的一个,每个子Schema绑定对应的move_type枚举值,同时明确该场景下的必填字段,Swagger文档会自动展示两种请求选项。- Serializer动态选择:视图内部根据
move_type的值切换对应的Serializer,确保必填字段的校验逻辑准确执行。 - 字段一致性:Swagger Schema中的字段类型、格式要和Serializer保持一致,比如
DateTimeField对应openapi.FORMAT_DATETIME,避免文档和实际校验不匹配。
内容的提问来源于stack exchange,提问作者S.K
相关产品推荐
相关产品推荐

