You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:55:33