DRF自动生成OpenAPI文档

2021-12-21 16:02:05 浏览数 (1)

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

关于更多的使用方法,请参考文档

0 人点赞