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

drf-yasg嵌套序列化器Swagger文档缺失openning_time字段及报错解决

问题分析与解决方案

问题根源

  1. openning_time字段在序列化器中设置了read_only=True,Swagger自动生成请求体时会忽略只读字段,因为这类字段不属于请求参数范畴。
  2. 使用manual_parameters添加IN_BODY参数的方式不符合drf-yasg规范,它要求请求体必须通过request_body参数传入Schema或Serializer对象,这是触发报错的直接原因。

方案一:实现支持嵌套更新的序列化器(推荐)

如果需要实际接收并处理openning_time的更新数据,需要创建专用的更新序列化器,并手动实现嵌套字段的更新逻辑:

1. 修改序列化器

# serializers.py
class WarehouseUpdateSerializer(serializers.ModelSerializer):
    # 移除read_only=True,允许接收请求中的openning_time数据
    openning_time = OpenningTimeSerializer(many=True)

    class Meta:
        model = Warehouse
        fields = ['pk', 'name', 'action_available', 'openning_time', 'workers']

    # 覆盖update方法,处理嵌套的开放时间数据
    def update(self, instance, validated_data):
        # 提取嵌套的开放时间数据
        openning_times_data = validated_data.pop('openning_time', None)
        # 先更新Warehouse本身的字段
        instance = super().update(instance, validated_data)
        
        # 根据业务逻辑处理开放时间的更新(示例:删除旧数据后创建新数据)
        if openning_times_data:
            instance.openning_time.all().delete()
            for time_data in openning_times_data:
                OpenningTime.objects.create(warehouse=instance, **time_data)
        return instance

2. 配置Swagger视图

# views.py
from drf_yasg.utils import swagger_auto_schema

class WarehouseApi(mixins.RetrieveModelMixin,
                mixins.UpdateModelMixin,
                mixins.ListModelMixin,
                viewsets.GenericViewSet):

    queryset = Warehouse.objects.all()
    serializer_class = WarehouseSerializer
    permission_classes = [IsAuthenticated, ]

    @swagger_auto_schema(
        request_body=WarehouseUpdateSerializer,
        responses={200: WarehouseSerializer}
    )
    def update(self, request, *args, **kwargs):
        # 指定更新操作使用的序列化器
        self.serializer_class = WarehouseUpdateSerializer
        return super().update(request, *args, **kwargs)

方案二:仅在Swagger中显示字段(临时需求)

如果不需要实际处理嵌套更新,只是希望Swagger文档中显示openning_time字段,可以直接用openapi.Schema定义请求体结构:

# views.py
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

class WarehouseApi(mixins.RetrieveModelMixin,
                mixins.UpdateModelMixin,
                mixins.ListModelMixin,
                viewsets.GenericViewSet):

    queryset = Warehouse.objects.all()
    serializer_class = WarehouseSerializer
    permission_classes = [IsAuthenticated, ]

    @swagger_auto_schema(
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'name': openapi.Schema(type=openapi.TYPE_STRING),
                'action_available': openapi.Schema(type=openapi.TYPE_BOOLEAN),
                'workers': openapi.Schema(type=openapi.TYPE_INTEGER),
                'openning_time': openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(
                        type=openapi.TYPE_OBJECT,
                        properties={
                            'weekday': openapi.Schema(type=openapi.TYPE_INTEGER),
                            'from_hour': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_TIME),
                            'to_hour': openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_TIME),
                        },
                        required=['weekday', 'from_hour', 'to_hour']
                    )
                )
            },
            required=['name'] # 根据实际业务设置必填字段
        ),
        responses={200: WarehouseSerializer}
    )
    def update(self, request, *args, **kwargs):
        return super().update(request, *args, **kwargs)

注意事项

  • DRF默认不会自动处理嵌套序列化器的更新逻辑,必须手动覆盖update方法实现业务逻辑。
  • read_only=True会让字段仅出现在响应中,若需要在请求中接收该字段,必须移除该参数或调整为write_only=True(仅写入不返回)。

内容的提问来源于stack exchange,提问作者Pytolong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 03:54:15