Python中Django Swagger文档的一个常见坑点及解决方案

最近在写项目,搭建了新的服务, 以前都是使用 ip 直接请求的, 后来加上了域名,发现 docs 请求的文档都是, 本地的 ip, 后来在网上一查发现原来,需要在 nginx 中加入参数 proxy_set_header,就可解决:
server {
listen 80;
server_name ******.com;
location / {
proxy_set_header Host $host;
}
}
Python中Django Swagger文档的一个常见坑点及解决方案


3 回复

我最近在Django项目里集成Swagger文档时也踩过这个坑。最常见的问题就是drf-yasgdrf-spectacular这类库在自动生成schema时,经常无法正确识别某些复杂序列化器(Serializer)或视图集(ViewSet)的字段结构,导致生成的API文档里字段缺失、类型错误,或者直接报AssertionError

核心原因:Django REST framework的序列化器有时在嵌套关系(serializers.SerializerMethodFieldsource参数深度映射、或many=True的嵌套序列化)上,Swagger的schema生成器无法在静态分析阶段完全推断出数据结构。

解决方案:手动通过@swagger_auto_schema装饰器或OpenApiParameter等类来补充或覆盖自动生成的schema信息。

举个例子,假设你有一个带SerializerMethodField的序列化器:

from rest_framework import serializers
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

class MySerializer(serializers.Serializer):
    id = serializers.IntegerField()
    extra_info = serializers.SerializerMethodField()

    def get_extra_info(self, obj):
        # 一些复杂逻辑返回字典
        return {"key": "value"}

# 在视图中手动补充字段描述
class MyAPIView(APIView):
    @swagger_auto_schema(
        responses={
            200: openapi.Response(
                description="成功返回",
                schema=MySerializer,
                examples={"application/json": {"id": 1, "extra_info": {"key": "example"}}}
            )
        },
        manual_parameters=[
            openapi.Parameter('some_param', openapi.IN_QUERY, description="测试参数", type=openapi.TYPE_STRING)
        ]
    )
    def get(self, request):
        # 视图逻辑
        pass

对于更复杂的嵌套,可以直接定义完整的OpenApiSchema

from drf_yasg import openapi

custom_schema = openapi.Schema(
    type=openapi.TYPE_OBJECT,
    properties={
        'id': openapi.Schema(type=openapi.TYPE_INTEGER),
        'extra_info': openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={'key': openapi.Schema(type=openapi.TYPE_STRING)}
        )
    }
)

@swagger_auto_schema(responses={200: custom_schema})
def my_view(request):
    ...

总结:遇到字段缺失或类型不对,别指望全自动,该手动声明schema时就手动声明。


好巧,我上周也发现并解决了这个问题🤓,我怎么就没想到要发个贴呢

回到顶部