DRF:认证、权限、频率、分页
Token认证
1、用户表设置token字段 2、写认证类MyAuth -继承BaseAuthentication -实现authenticate方法 写认证逻辑,返回user对象和token值 抛异常AuthenticationFailed,from rest_framework.exceptions import AuthenticationFailed 3、应用token认证 -单视图:authentication_classes = [MyAuth] authentication_classes = [] # 设置了全局认证,而某些视图不需要认证时 -全局使用:settings REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": ["***.MyAuth", ] } token放在url上传给后端 ?_token=asdasdas request.auth = request._request.GET.get("_token") = request.GET.get("_token")
from rest_framework.exceptions import AuthenticationFailed from authDemo.models import User from rest_framework.authentication import BaseAuthentication class MyAuth(BaseAuthentication): def authenticate(self, request): # 做认证 看他是否登录 # 从url过滤条件里拿到token # 去数据库看token是否合法 # 合法的token能够获取用户信息 token = request.query_params.get("token", "") if not token: raise AuthenticationFailed("没有携带token") user_obj = User.objects.filter(token=token).first() if not user_obj: raise AuthenticationFailed("token不合法") # return (None, None) return (user_obj, token)
class TestView(APIView): authentication_classes = [MyAuth,] permission_classes = [MyPermission, ] throttle_classes = [MyThrottle, ] def get(self, request): print(request.user) print(request.auth) user_id = request.user.id return Response("认证测试")
权限
1、用户表设置权限识别字段,枚举类型 2、写权限类:request, view两个参数 message: 认证失败返回的信息 has_permission:无权限return False 3、应用权限 视图中 permission_classes = [MyPermission, ]
from rest_framework.permissions import BasePermission class MyPermission(BasePermission): message = "您没有权限" def has_permission(self, request, view): # 判断用户是否有权限 user_obj = request.user if user_obj.type == 3: return False else: return True
频率:
频率限制单视图设置,不建议设置全站统一
1、写频率限制类 继承SimpleRateThrottle, 定义scope属性,实现get_cache_key方法 from rest_framework.throttling import SimpleRateThrottle class MyThrottle(SimpleRateThrottle): scope = "MyThrottle" def get_cache_key(self, request, view): # get_ident:以IP限制访问次数 # 如果以其他为限制依据,自定义方法 key = self.get_ident(request) return key 2、配置文件 REST_FRAMEWORK = { "DEFAULT_THROTTLE_RATES": {"MyThrottle": "3/m"} 类中定义的scope的值: 次数/时间 } s:1秒 m:60秒 h:1小时 3600秒 d:1天 3600*24秒 3、应用 视图中 throttle_classes = [MyThrottle, ]
分页
不需要在settings做设置
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination ********1******** class MyPagination(PageNumberPagination): # xxxx?page=1&size=2 # 如果路由上配置了size参数,则使用路由,否则使用默认page_size page_size = 1 page_query_param = "page" page_size_query_param = "size" max_page_size = 3 ********2******** class MyPagination(LimitOffsetPagination): # 路由必须传offset,limit可选, # 从第几条(offset)开始找几条(limit) default_limit = 1 limit_query_param = "limit" offset_query_param = "offset" max_limit = 3 ********3******** class MyPagination(CursorPagination): # 路由不需要传参数,且对分页信息加密 cursor_query_param = "cursor" page_size = 2 # 每页显示数据量 ordering = "-id" # 排序方式
视图继承APIView class BookView(APIView): def get(self, request): queryset = Book.objects.all() # 1,实例化分页器对象 page_obj = MyPagination() # 2,调用分页方法去分页queryset page_queryset = page_obj.paginate_queryset(queryset, request, view=self) # 3,把分页好的数据序列化返回 # 4, 带着上一页下一页连接的响应 ser_obj = BookSerializer(page_queryset, many=True) return page_obj.get_paginated_response(ser_obj.data) 视图继承GenericAPIView, ListModelMixin class BookView(GenericAPIView, ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = MyPagination # ***** # self.paginate_queryset(queryset) def get(self, request): return self.list(request)