DRF自动生成OpenAPI文档
API schemas是非常有用的,可以帮助我们生成接口文档以及可与API交互的动态客户端。Django REST Framework支持自动生成OpenAPI schemas,但是目前支持的不是非常完善,需要手动修改的地方过多。在这里我们使用drf-spectacular这个第三方库来自动生成OpenAPI schemas.
drf-spectacular
安装,配置步骤可以参考drf-spectacular文档,下面简单的给出步骤。
安装和配置
使用
经过上面的基本配置,我们现在访问api/schema/swagger-ui/
来查看swagger-ui风格的文档,如下所示:
当你点击schema的时候,就会显示响应字段的描述,而且会明确告知你,描述是从XXX序列化器取得的。下面给出相应的序列化器代码。
代码语言:javascript复制class BookInfoSerializer(serializers.Serializer):
"""BookInfo序列化器"""
id = serializers.IntegerField(label='书籍ID', read_only=True)
name = serializers.CharField(label='名称', max_length=10)
pub_date = serializers.DateField(label='发布日期')
readcount = serializers.IntegerField(label='阅读量', min_value=0, required=False)
commentcount = serializers.IntegerField(label='评论量', min_value=0, required=False)
我们看到的Schemas中的描述,description是来自于序列化器的文档字符串,而各个字段的title是来自于字段的label,带有*的意味着是必传的字段,除此之外,字段的其它描述是直接取自序列化器字段中的参数。 另外,对于该接口的描述也是直接来自文档字符串的内容。例如:
下面给出视图的代码
代码语言:javascript复制class BookListView(GenericAPIView):
"""列表视图"""
queryset = BookInfo.objects.all().order_by('id')
serializer_class = BookInfoSerializer
pagination_class = PageNum
def get(self, request):
"""GET请求获取列表"""
data = self.get_queryset() # 获取查询结果集
page = self.paginate_queryset(data) #对查询结果集进行分页
serializer = self.get_serializer(page, many=True) # 序列化
return Response(serializer.data) # 返回值
def post(self, request):
"""post请求新增"""
data = request.data
serializer = self.get_serializer(data=data)
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=201)
else:
# 返回错误信息
return Response({'msg': '保存失败'}, status=400)
对于HTTP Body中的内容,都在序列化器中描述了,但是对于URL参数,是默认没有描述的。我们需要手动修改,如下所示:
手动在代码中加入以下内容:
代码语言:javascript复制class BookView(GenericAPIView):
"""删改查视图"""
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
lookup_field = 'pk'
lookup_url_kwarg = 'pk'
@extend_schema(parameters=[OpenApiParameter(name='id', description='书籍唯一id', required=True, type=int, location=OpenApiParameter.PATH)])
def get(self, request, pk):
"""根据id查询书籍详情"""
obj = self.get_object()
serializers = self.get_serializer(obj)
更多的信息,需要参考OpenAPI的规范,有一篇不错的文章,可以看看OpenAPI 规范摘要。 drf-spectacular自动生成文档,很大程度上依赖于文档字符串以及queryset和serializer_class(DRF的APIView没有这两个属性,对于APIView自动生成文档有困难,当然你可以直接在APIView中定义这两个属性,但是会显得很奇怪。)
在视图集中使用
对于视图集而言,可以使用@extend_schema_view装饰器来直接装饰类。例如:
代码语言:javascript复制@extend_schema_view(
list=extend_schema(description='列表'),
create=extend_schema(description='新增'),
retrieve=extend_schema(description='查询一个',parameters=[
'id', OpenApiParameter("id", OpenApiTypes.INT, OpenApiParameter.PATH, description="书籍ID"),],),
update=extend_schema(description='更新一个'),
partial_update=extend_schema(description='部分更新'),
destroy=extend_schema(description='删除一个'),
)
class BookModelViewSet(ModelViewSet):
"""书籍视图集"""
queryset = BookInfo.objects.all().order_by('id')
serializer_class = BookInfoSerializer
pagination_class = PageNum
lookup_field = 'id'
lookup_url_kwarg = 'id'
lookup_url_description = '书籍id'
上面这里方法和属性来自于下面的导入操作:
代码语言:javascript复制from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample, extend_schema_view, OpenApiTypes
关于更多的使用方法,请参考文档