DRF自动生成OpenAPI文档
API schemas是非常有用的,可以帮助我们生成接口文档以及可与API交互的动态客户端。Django REST Framework支持自动生成OpenAPI schemas,但是目前支持的不是非常完善,需要手动修改的地方过多。在这里我们使用drf-spectacular这个第三方库来自动生成OpenAPI schemas.
drf-spectacular
安装,配置步骤可以参考drf-spectacular文档,下面简单的给出步骤。
安装和配置
- 安装要求
Python >= 3.6
Django (2.2, 3.1, 3.2)
Django REST Framework (3.10, 3.11, 3.12)
- 安装
pip3 install drf-spectacular[sidecar]
- 注册
在settings.py文件中,进行注册。
INSTALLED_APPS = [
...
'drf_spectacular',
'drf_spectacular_sidecar',
]
- 配置
SPECTACULAR_SETTINGS = {
'TITLE': 'Your Project API',
'DESCRIPTION': 'Your project description',
'VERSION': '1.0.0',
'SWAGGER_UI_DIST': 'SIDECAR', # shorthand to use the sidecar instead
'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
'REDOC_DIST': 'SIDECAR',
}
REST_FRAMEWORK = {
# YOUR SETTINGS
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
使用
- 直接生成yaml文件,然后配合swagger-ui来使用
python3 manage.py spectacular --file schema.yml
- 使用swagger-ui或redoc来展现
一般情况,我们都是直接使用swagger-ui或者redoc来展现的。需要在urlpatterns中做如下的设置。
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [
# YOUR PATTERNS
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
# Optional UI:
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
经过上面的基本配置,我们现在访问api/schema/swagger-ui/
来查看swagger-ui风格的文档,如下所示:
当你点击schema的时候,就会显示响应字段的描述,而且会明确告知你,描述是从XXX序列化器取得的。下面给出相应的序列化器代码。
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,带有*的意味着是必传的字段,除此之外,字段的其它描述是直接取自序列化器字段中的参数。
另外,对于该接口的描述也是直接来自文档字符串的内容。例如:
下面给出视图的代码
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参数,是默认没有描述的。我们需要手动修改,如下所示:
手动在代码中加入以下内容:
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装饰器来直接装饰类。例如:
@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'
上面这里方法和属性来自于下面的导入操作:
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample, extend_schema_view, OpenApiTypes
关于更多的使用方法,请参考文档