Django drf-yasg中@swagger_auto_schema如何为@api_view配置精简request_body序列化器
解决方案
针对你的需求,有两种常用的实现方式:
方案1:拆分序列化器(更推荐,复用性强)
基于原有PostSerializer继承得到创建场景专用的序列化器,移除不需要用户传入的字段,既可以解决swagger文档的展示问题,也能避免序列化器校验时要求传入creator的逻辑问题。
- 调整
serializer.py代码:
class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ('creator', 'body', 'uuid', 'created', 'updated_at') # 新增创建场景专用序列化器 class PostCreateSerializer(PostSerializer): class Meta(PostSerializer.Meta): # 排除不需要用户传入的字段 exclude = ('creator',) # 也可以直接指定仅开放给用户传入的字段 # fields = ('body',)
- 调整
view.py的装饰器配置:
@api_view(['POST']) @swagger_auto_schema( operation_description="Create a post object", request_body=PostCreateSerializer # 指定请求体对应子集序列化器 ) def post_create(request): try: request.data['creator'] = str(request.user.uuid) # 也可以直接用PostCreateSerializer做校验,逻辑更严谨 post_serializer = PostSerializer(data=request.data) if post_serializer.is_valid(raise_exception=True): post_obj = post_serializer.save() except ValidationError as e: return Response(dict(error=str(e), user_message=error_message_generic), status=status.HTTP_400_BAD_REQUEST) return Response(post_serializer.data, status=status.HTTP_201_CREATED)
方案2:直接在装饰器内定义请求结构(适合单接口一次性使用场景)
如果不想额外新增序列化器,可以直接通过drf-yasg的OpenApiSchema手动定义请求体结构:
- 先导入依赖:
from drf_yasg import openapi
- 调整装饰器配置:
@api_view(['POST']) @swagger_auto_schema( operation_description="Create a post object", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['body'], properties={ 'body': openapi.Schema(type=openapi.TYPE_STRING, description='帖子内容') } ) ) def post_create(request): # 原有视图逻辑保持不变即可
额外优化建议
当前代码中如果用户主动传入creator参数,会被你手动赋值的用户uuid覆盖,更严谨的做法是将原PostSerializer的creator字段设置为只读,避免逻辑漏洞,同时如果直接把request_body设置为加了只读属性的PostSerializer,swagger也会自动把creator标记为只读,不会出现在请求参数列表中:
class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ('creator', 'body', 'uuid', 'created', 'updated_at') extra_kwargs = { 'creator': {'read_only': True} }
内容的提问来源于stack exchange,提问作者user12314098
相关产品推荐
相关产品推荐

