过滤和分页源码
补充
-filter_backends = [SearchFilter,MyFilter]
-GenericAPIView:继承APIVIew的视图类,是不能这样配置的----》自己过滤
-filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
-还需要继承:ListModelMixin---》它的list方法中,在对所有数据做过滤:queryset = self.filter_queryset(self.get_queryset())
-self.filter_queryset如何做的过滤呢?ListModelMixin类中没有这个方法,最终从GenericAPIView中找到了
-GenericAPIView的filter_queryset干了啥事?
def filter_queryset(self, queryset):
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
- pagination_class = CommonCursorPagination
-pagination_class是GenericAPIView的类属性:继承APIVIew的视图类,是不能这样配置的----》自己分页
-还需要继承:ListModelMixin---》它的list方法中,在对所有数据做了分页--》
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
-self.paginate_queryset(queryset)是 GenericAPIView 类的方法
- GenericAPIView的 paginate_queryset
def paginate_queryset(self, queryset):
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
-self.paginator 方法包装成了属性,就是咱们分页类的对象 CommonCursorPagination()
@property
def paginator(self):
self._paginator = self.pagination_class()
return self._paginator
- 调用了 分页类对象的paginate_queryset---》完成真正的分页
分页类对象.paginate_queryset(queryset, self.request, view=self)
-APIView执行流程---》dispatch的
try:
except Exception as exc:
response = self.handle_exception(exc)
-执行:self.handle_exception(exc)---》self是视图类的对象
-APIView的handle_exception(exc)
-handle_exception源码
def handle_exception(self, exc):
exception_handler = self.get_exception_handler()
response = exception_handler(exc, context)
return response
-self.get_exception_handler()是如何从配置文件中拿出来的
-self.settings.EXCEPTION_HANDLER
-1 这个错误不是在三大认证和视图类的方法中产生的,之前产生的--》中间件,包装新的request
-2 你写的common_exception执行出错了
1 接口文档
1 word ,md ,写好传到公司的某个平台---》前端可以下载
2 自动生成接口文档---》后端通过配置--》把所写的接口都自动生成---》地址--》访问这个地址就能看到所有接口文档
3 公司内部搭建接口文档平台
- 开源:Yapi--->同学搭建一个,给搭建用
-https://zhuanlan.zhihu.com/p/366025001
- 自己开发(自研)
4 使用第三方平台(花钱)-->showdoc ....
-以用户注册接口为例:
1 接口描述
2 请求地址
3 请求方式
4 编码格式:json,urlencoded,form-data
5 请求参数:参数详解
-请求地址参数
-请求体参数
6 返回格式示例--》返回参数说明
7 备注(可有可无)--》错误码
-coreapi,swagger:drf-yasg
第一步:pip install coreapi
第二步:设置接口文档访问路径
from rest_framework.documentation import include_docs_urls
urlpatterns = [
...
path('docs/', include_docs_urls(title='站点页面标题'))
]
第三步:在视图中,加注释
第四步:配置文件配置
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
2 jwt介绍和构成
-https://www.cnblogs.com/liuqingzheng/p/8990027.html
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
-一般放公司信息,加密方式(没放秘钥)
-当前用户的信息:用户名,用户id,token过期时间。。。
-第一部分和第二部分通过加密得到的字符串
3 jwt签发与认证
-签发:(登录接口)
-登录接口,登录成功,签发token(三段式)
-header,用base64编码,暂放
{"company": "公司信息",}
-payload,用base64编码,暂放
{用户名,用户权限,过期时间}
-使用加密方式:md5,把header和payload 都update进md5中---》生成前面---》base64编码
-三段拼接起来---》用 . 分割
-认证(认证类)
-用户携带token过来,认证
-取出第一部分header
-取出第二部分 payload
-使用之前同样的加密算法(密码),得到新前面
-跟token的第三部分比较,如果一样,表示没有被窜改,顺利继续往下走,返回两个值
-如果被篡改了,抛异常
4 base64编码
1 token串使用base64编码
2 互联网中前后端数据交互,可以使用base64编码
3 图片二进制可以使用base64编码传递
import json
import base64
img='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'
res=base64.b64decode(img)
with open('xx.png','wb') as f:
f.write(res)
5 drf-jwt使用
-django-rest-framework-jwt:有点老
-djangorestframework-simplejwt:新的
-自己写:https://gitee.com/liuqingzheng/rbac_manager/blob/master/libs/lqz_jwt/token.py
pip install djangorestframework-jwt
5.1 django-rest-framework-jwt快速使用
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('login/', obtain_jwt_token),
]
-视图类上,配置认证类和权限类
authentication_classes = [JSONWebTokenAuthentication,]
permission_classes = [IsAuthenticated]
5.3 定制签发返回格式
def jwt_response_payload_handler(token, user=None, request=None):
return {
'status': 100,
'msg': '登录成功',
'token': token,
'username': user.username
}
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.response.jwt_response_payload_handler',
}
5.4 obtain_jwt_token源码分析
path('login/', obtain_jwt_token),
class ObtainJSONWebToken(JSONWebTokenAPIView):
serializer_class = JSONWebTokenSerializer
-登录走的是JSONWebTokenAPIView的post,签发token 是在序列化类中
-签发完token执行了,咱们写的jwt_response_payload_handler,所以才能定制返回格式