Python 学习笔记(十三)---Archery API 接口开发
1.什么是swagger
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful 风格的 Web 服务。Swagger的目标是对REST API定义一个标准的和语言无关的接口,可让人和计算机无需访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过Swagger进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。类似于低级编程接口,Swagger去掉了调用服务时的很多猜测.
swagger的优点:
(1). swagger 可以根据代码自动生成 API 文档,很好的保证了文档的时效性,做到了代码变,文档变;
(2). swagger UI 呈现出来的是一份可交互式的 API 文档,我们可以直接在文档页面尝试 API 的调用,省去了准备复杂的调用参数的过程;
(3). 可以将swagger文档规范导入相关的工具(例如 Postman、AgileTC), 这些工具将会为我们自动地创建自动化测试。
2.archery 中关于Swagger的设置
2.1 在archery/settings.py中关于Swagger的设置
# Application definition INSTALLED_APPS = ( .... "drf_spectacular", ... )
# Swagger UI SPECTACULAR_SETTINGS = { "TITLE": "Archery API", "DESCRIPTION": "OpenAPI 3.0", "VERSION": "1.0.0", }
2.2 在sql_api/urls.py中的设置
###引入的模块 from drf_spectacular.views import ( SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView, )
2.3 url路径设置
urlpatterns = [ ...... path( "swagger/", SpectacularSwaggerView.as_view(url_name="sql_api:schema"), name="swagger", ),
........, ]
3.接口案例说明
archery 已开发的接口文档,可以参照https://demo.archerydms.com/api/redoc/网址。
3.1 用户清单
https://demo.archerydms.com/api/v1/user/
功能列出所有用户(过滤,分页)
3.2 其中sql_api/urls.py中url的设置
path("v1/user/", api_user.UserList.as_view()),
3.3 功能代码的位置
功能代码的文件为sql_api/api_user.py
class UserList(generics.ListAPIView): """ 列出所有的user或者创建一个新的user """ filterset_class = UserFilter pagination_class = CustomizedPagination serializer_class = UserSerializer queryset = Users.objects.all().order_by("id") @extend_schema( summary="用户清单", request=UserSerializer, responses={200: UserSerializer}, description="列出所有用户(过滤,分页)", ) def get(self, request): users = self.filter_queryset(self.queryset) page_user = self.paginate_queryset(queryset=users) serializer_obj = self.get_serializer(page_user, many=True) data = {"data": serializer_obj.data} return self.get_paginated_response(data) @extend_schema( summary="创建用户", request=UserSerializer, responses={201: UserSerializer}, description="创建一个用户", ) def post(self, request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
3.4 调试
在线格式化后
(1)返回的数据里面有一个 count ,表示数据的总条数
(2)next 表示 下一页的 url (包含域名),这里面可以传很多参数,比如 按什么排序、按什么搜索等,这些关键词都会加入到这个 url 里面来。
(3)results 里面是我们需要的列表 数据。
4.既有版本升级
我们知道1.8.3 到 1.8.4 / 5 升级的亮点是 关于 API 接口的支持 :
* Restful API * 新增配置项API_USER_WHITELIST * 新增OpenAPI swagger菜单
需要特别注意的是,一定要 修改 common/middleware/check_login_middleware.py,中的代码,
否则,执行的时候,总是路由重定向(状态码:302 ),转向了 登陆界面。
将
IGNORE_URL_RE = r'/admin/\w*'
调整为
IGNORE_URL_RE = r'(/admin/\w*|/api/(v1|auth)/\w+)'
该部分的代码 :在每个函数之前检查是否登录,若未登录,则重定向到/login/
版本升级 更多内容,请参照https://github.com/hhyo/Archery/commit/a952075308cf942a2ab6a343c49da37638504520
5.相关知识加油点
5.1 类视图
- 在Django中也可以使用类来定义一个视图,称为类视图
- 使用类视图可以将视图对应的不同请求方式以类中的不同方法来区别定义。
类视图的好处:代码可读性好,类视图相对于函数视图有更高的复用性 , 如果其他地方需要用到某个类视图的某个特定逻辑,直接继承该类视图即可。
APIView
是REST framework提供的所有视图的基类,继承自Django的View
父类。
APIView的一般导入方式
from rest_framework.views import APIView from rest_framework.response import Response class ClassName(APIView): .....
或者
from rest_framework import views from rest_framework.response import Response ###在继承的时候,在指明APIView class ClassName(views.APIView):
APIView
与View
的不同之处在于:
- 传入到视图方法中的是REST framework的
Request
对象,而不是Django的HttpRequeset
对象; - 视图方法可以返回REST framework的
Response
对象,视图会为响应数据设置(render)符合前端要求的格式; - 任何
APIException
异常都会被捕获到,并且处理成合适的响应信息; - 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
支持定义的属性
- authentication_classes 列表或元组,身份认证类
- permissoin_classes 列表或元组,权限检查类
- throttle_classes 列表或元组,流量控制类
在APIView
中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。
5.2 GenericAPIView
queryset """ 必须指定,用于从视图返回对象的查询结果集,通常,你必须设置此属性或者重写get_queryset()方法, 如果你重写了一个视图的方法,你应该调用get_queryset()而不是直接访问该属性,因为queryset将被计算一次 这些结果将为后续请求存储起来 """
serializer_class
serializer_class """ 用户验证和反序列化输入以及用户序列号输出的serializer类,通常,你必须设置此属性或者重写get_serializer_class()方法 """
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field
lookup_field """ 用于执行各个model实例的对下查找的model字段,默认为pk 注意:在使用超链接API时,如果需要使用自定义的值,需要确保在API和序列化类中都设置查找字段 """
lookup_url_kwarg
lookup_url_kwarg """ 用于对象查找url关键字参数,他的url conf应该包括这应该与这个指相对于的关键字参数,如果取消设置 默认情况下使用与lookup_field相同的值 """
get_queryset()
get_queryset() """ 返回list视图中使用的查询集,该查询集还用做detail视图中的查找基础,默认返回由queryset属性指定的查询集 平时我们应该多使用这个方法,而不是直接访问self.queryset,因为self.queryset只会被提交一次 然后这些结果将为后续请求缓存起来,该方法可能会被重写以提供动态行为 """
""" Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using `self.queryset`. This method should always be used rather than accessing `self.queryset` directly, as `self.queryset` gets evaluated only once, and those results are cached for all subsequent requests. You may want to override this if you need to provide different querysets depending on the incoming request. (Eg. return a list of items that is specific to the user) """
get_object()
get_object() """ 返回用于detail视图的对象实例,默认使用look_up_field参数过滤基本的查询集 该方法可以被重写以提供更复杂的行为,例如基于多个url参数的对象查找 """
""" Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. """
filter_queryset
filter_queryset """ 给定一个queryset,使用任何过滤器后端进行过滤,返回一个新的queryset """
""" Given a queryset, filter it with whichever filter backend is in use. You are unlikely to want to override this method, although you may need to call it either from a list view, or from a custom `get_object` method if you want to apply the configured filtering backend to the default queryset. """
5.3 drf-spectacular
drf-spectacular
是为Django REST Framework
生成合理灵活的OpenAPI 3.0
模式。它可以自动帮我们提取接口中的信息,从而形成接口文档,而且内容十分详细,再也不用为写接口文档而心烦了
这个库主要实现了3个目标
- 从DRF中提取更多的schema信息
- 提供灵活性,使schema在现实世界中可用(不仅仅是示例)
- 生成一个与最流行的客户端生成器配合良好的schema
5.4 数据即是资源
接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
- https://api.baidu.com/users
- https://api.baidu.com/books
- https://api.baidu.com/book
注:一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user
资源操作由请求方式决定,操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
- https://api.baidu.com/books - get请求:获取所有书
- https://api.baidu.com/books/1 - get请求:获取主键为1的书
- https://api.baidu.com/books - post请求:新增一本书书
- https://api.baidu.com/books/1 - put请求:整体修改主键为1的书
- https://api.baidu.com/books/1 - patch请求:局部修改主键为1的书
- https://api.baidu.com/books/1 - delete请求:删除主键为1的书
5.5 查看源码 分析 APIView 如何 继承自Django的View
父类
文档路径【....\venv\Lib\site-packages\..】
在 rest_framework中找到APIView
打开 APIView的定义
我们清楚地看出,继承自 View 类。那么View类来自哪儿?
翻到最上面,import 地方,可以看到 如下:
from django.views.generic import View
我们继续查找,就会看到就是来自diango部分。层级也完全符合。
APIView 果然是继承自Django的View
父类。
6.参考学习
(1) 通用视图GenericAPIView、属性和方法
https://www.cnblogs.com/Mickey-7/p/16499565.html
(2) 视图--视图类
https://www.cnblogs.com/longan-wang/p/15175127.html
(3) Django(74)drf-spectacular自动生成接口文档
https://www.cnblogs.com/jiakecong/p/15488852.html
(4) Archery 代码
https://gitee.com/rtttte/Archery
(5) Django Swagger文档库drf-spectacular
https://www.imooc.com/article/328974
(6) https://www.cnblogs.com/xiaoyuanqujing/category/1566356.html
(7) Django REST Framework通用View
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
2018-09-18 如何在MongoDB设计存储你的数据(JSON化)?