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

使用drf-spectacular时如何让Swagger示例区展示主键id字段

问题原因

DRF的ModelSerializer默认会将模型主键id标记为只读字段,drf-spectacular生成OpenAPI Schema时,请求体示例默认仅包含可写字段,因此id不会出现在Swagger的请求示例区域。

最优解决方案

方案1:直接修改序列化器字段属性(适合序列化器仅用于写操作/确实需要接收id参数的场景)

直接在序列化器中显式设置id为可写字段即可,drf-spectacular会自动将其加入请求示例:

# Serializers.py
class SerializerExample(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('id','name')
        # 新增这段配置,将id设为可写
        extra_kwargs = {
            'id': {'read_only': False}
        }

方案2:继承原有序列化器创建专用子类(适合原序列化器其他场景需要id为只读的场景)

不用修改原有序列化器逻辑,仅为当前批量更新接口创建一个子类继承原序列化器,仅修改id的只读属性,后续原序列化器新增/修改字段会自动同步到子类,无需重复维护:

# Serializers.py
# 原有序列化器保持不变,其他接口继续使用
class SerializerExample(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('id','name')

# 新增批量更新专用子类
class SerializerExampleForBulkUpdate(SerializerExample):
    class Meta(SerializerExample.Meta):
        extra_kwargs = {
            'id': {'read_only': False}
        }

视图中修改extend_schema的request参数即可:

# Views.py
class BooksBulkUpdate(APIView):
    @extend_schema(
        request=SerializerExampleForBulkUpdate(many=True),
        responses={200:''},
    )
    def put(self, request, format=None):
        # 原有逻辑不变
        with transaction.atomic():
            for data in request.data:
                book = Book.objects.get(pk=data['id'])
                serializer = SerializerExample(book, data=data, partial=True)
                if serializer.is_valid():
                    serializer.save()
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        return Response()

方案3:直接指定自定义示例(适合不想修改序列化器的场景)

无需改动序列化器逻辑,直接在extend_schema中显式指定请求示例:

# Views.py
from drf_spectacular.utils import extend_schema, OpenApiExample

class BooksBulkUpdate(APIView):
    @extend_schema(
        request=SerializerExample(many=True),
        responses={200:''},
        examples=[
            OpenApiExample(
                '批量更新书籍示例',
                value=[
                    {'id': 1, 'name': '新书名1'},
                    {'id': 2, 'name': '新书名2'}
                ],
                request_only=True,
            )
        ]
    )
    def put(self, request, format=None):
        # 原有逻辑不变
        with transaction.atomic():
            for data in request.data:
                book = Book.objects.get(pk=data['id'])
                serializer = SerializerExample(book, data=data, partial=True)
                if serializer.is_valid():
                    serializer.save()
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        return Response()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 18:27:00