drf——权限、认证源码分析、过滤、排序、分页
2023/5/26 1:22:04
本文主要是介绍drf——权限、认证源码分析、过滤、排序、分页,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
权限、认证源码(了解)
权限源码
# 继承了APIView才有的---》执行流程---》dispatch中的三大认证 self.initial(request, *args, **kwargs) # 1. APIView的dispatch中self.initial(request, *args, **kwargs) def initial(self, request, *args, **kwargs): self.perform_authentication(request) # 认证 self.check_permissions(request) # 权限 self.check_throttles(request) # 频率 # 2. 读权限:APIView的方法self.check_permissions(request) def check_permissions(self, request): for permission in self.get_permissions(): # self.get_permissions()是我们配置在视图类中permission_classer列表中的认证类实例化出来的一个一个对象 """ permission_classes = [AdminPermission,] self.get_permissions()是AdminPermission()实例化出的对象 """ if not permission.has_permission(request, self): # 权限没通过会执行 # 写的权限类需要重写has_permission方法 # permission是自己写的权限类的对象 # 对象点方法时 先从自己类中找has_permission # 后面括号中的self参数是视图类的对象 self.permission_denied( request, message=getattr(permission, 'message', None), # self.message 错误文字 code=getattr(permission, 'code', None) ) # 3. APIView中的self.get_permissions() def get_permissions(self): return [permission() for permission in self.permission_classes] """ permission_classes是我们配置在视图类中的权限类 self是自己写的视图类的对象 self.permission_classes获取所有配置的权限类 列表生成式 也可以写成 l = [] for permission in self.permission_classes l.append(permission()) return l """ # 返回一个列表 列表中是一个个自己写的权限类的对象 # 总结 写的权限类 一定要写一个方法has_permission,返回True或False 不写则报错 配置在视图类上
认证源码
# 继承了APIView才有的---》执行流程---》dispatch中的三大认证 self.initial(request, *args, **kwargs) # 1. APIView的dispatch中self.initial(request, *args, **kwargs) def initial(self, request, *args, **kwargs): self.perform_authentication(request) # 认证 self.check_permissions(request) # 权限 self.check_throttles(request) # 频率 # 2. self.perform_authentication(request) def perform_authentication(self, request): request.user # user这是个方法 包装成了数据属性 """ 此时的request是走三大认证之前 dispatch中重新定义了新的request request = self.initialize_request(request, *args, **kwargs) """ # 3. Request类中的user @property def user(self): if not hasattr(self, '_user'): with wrap_attributeerrors(): self._authenticate() return self._user # 4. Request类的self._authenticate() def _authenticate(self): for authenticator in self.authenticators: """ self.authenticators就是你写的认证类列表 authenticators是在定义新的request时self.initialize_request调用这个方法的时候 return出的authenticators=self.get_authenticators(), get_authenticators是APIView中的方法 def get_authenticators(self): return [auth() for auth in self.authentication_classes] 循环视图类中的类属性authentication_classes获取列表中的每个认证类 然后给认证类加括号 实例化得到对象 再返回 即 authenticators是认证类实例化得到的对象放在列表中 authenticator是一个个认证类实例化的对象 """ try: user_auth_tuple = authenticator.authenticate(self) # authenticate是在认证类中重写的方法 如果认证成功返回的是元祖(user,token) except exceptions.APIException: # 抛了异常被捕获了 if user_auth_tuple is not None: # 如果返回有值即认证通过执行 # self是Request的对象 self.user, self.auth = user_auth_tuple # (user,token) return self._not_authenticated() # 总结 1.认证类 必须写一个方法authenticate 2.如果认证通过 可以返回None,也可以返回两个值 但是第一个值尽量是当前登录用户 第二个值一般放token 3.认证失败 抛异常AuthenticationFailed('你没有登录,不能访问'),它继承了APIException,他能捕获
补充 Django中的国际化
# 只要做了国际化 会自动翻译成,当前国家的语言 from django.utils.translation import gettext_lazy as _ _('hello')
排序
# restful规范中 -请求地址中带过滤条件 # 排序功能的接口:查询所有 from rest_framework.filters import OrderingFilter class BookView(GenericViewSet,ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [OrderingFilter] # 排序类 ordering_fields = ['price','id'] # 指定哪些字段可以排序 # ordering = ['id'] # 默认排序 # http://127.0.0.1:8000/api/v1/books/?ordering=-price,-id # -是倒序 先按价格倒序排 再按id倒序排
过滤
# restful规范中 -请求地址中带过滤条件 # 带过滤的接口只有:查询所有 '''1.内置过滤类''' from rest_framework.filters import SearchFilter class BookView(GenericViewSet,ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [SearchFilter] # search_fields = ['name'] # http://127.0.0.1:8000/api/v1/books/?search=红 # 只要name中有红的都能搜索出 search_fields = ['name','price'] # http://127.0.0.1:8000/api/v1/books/?search=11 # 只要name或者price中带有11的都能搜出来 '''2.第三方过滤类''' # pip38 install django-filter # 下载之后如果要使用的话 必须去配置文件INSTALLED_APPS下注册才可 from django_filters.rest_framework import DjangoFilterBackend class BookView(GenericViewSet,ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = [DjangoFilterBackend] filterset_fields = ['name','price'] # http://127.0.0.1:8000/api/v1/books/?name=红楼梦&price=45 # 按名字和价格精准匹配 '''3.自定义过滤类 很复杂的搜索 自己来写''' '''视图类''' from .filter import MyFilter from rest_framework.filters import OrderingFilter class BookView(GenericViewSet,ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer # filter_backends = [MyFilter] # http://127.0.0.1:8000/api/v1/books/?name=红楼梦&price=11 # 过滤出name为红楼梦或者price为11的 # 过滤类可以配多个 执行顺序是从左往右 filter_backends = [MyFilter,OrderingFilter] ordering_fields = ['price'] # http://127.0.0.1:8000/api/v1/books/?price=44&name=红楼梦&ordering=-price # 过滤出name为红楼梦或者price为44的并且按价格降序排序 '''自定义过滤类''' from rest_framework import filters from django.db.models import Q class MyFilter(filters.BaseFilterBackend): # 重写父类中的方法 返回的数据就是过滤后的数据 def filter_queryset(self, request, queryset, view): price = request.query_params.get('price') name = request.query_params.get('name') queryset = queryset.filter(Q(price=price) | Q(name=name)) return queryset
分页
# 查询所有接口,过滤和排序了,但是实际上,这个接口,都需要有分页功能 -分页的展现形式 web:下一页点击 app,小程序:下滑下一页 -接口都一样,要支持分页 # 带过滤的接口只有:查询所有 # drf提供给咱们,三种分页方式 # 基本分页 # 偏移分页 # 游标分页 '''视图类''' '''分页 --->>> 必须是获取所有的接口 必须继承GenericAPIView及其子类''' from .page import MyPageNumberPagination,MyLimitOffsetPagination,MyCursorPagination class BookView(GenericViewSet,ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer # pagination_class = MyPageNumberPagination # 只能按一种方式分页,不要放到列表中了 # # http://127.0.0.1:8000/api/v1/books/?page=1&page_size=3 # # 查询第1页 每页显示3条 # pagination_class = MyLimitOffsetPagination # # http://127.0.0.1:8000/api/v1/books/?limit=4&offset=3 # # 从第三条数据开始,取4条 pagination_class = MyCursorPagination # 只有上一页和下一页 '''分页类 page.py''' from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination # 基本分页 class MyPageNumberPagination(PageNumberPagination): # 重写的几个类属性 4个 page_size = 2 # 每页显示的条数 page_query_param = 'page' # page=4 表示第4页 page_size_query_param = 'page_size' # page=4&page_size=5 表示查询第4页每页显示5条 max_page_size = 5 # 每页最大显示多少条 # 偏移分页 class MyLimitOffsetPagination(LimitOffsetPagination): # 重写几个类属性 :4个 default_limit = 2 # 每页显示多少条 limit_query_param = 'limit' # limit=3 这一页取3条 offset_query_param = 'offset' # 偏移量是多少 offset=3&limit=2 从第三条开始拿两条 max_limit = 5 # 最多取5条 # 游标分页,只能上一页和下一页,不能直接跳到某一页,但是这个的速度快---》app上用它多 class MyCursorPagination(CursorPagination): # 重写几个类属性 :3个 cursor_query_param = 'cursor' # 查询参数,其实用不到 page_size = 2 # 每页显示多少条 ordering = 'id' # 必须是要分页的数据表中的字段 一般按id来
这篇关于drf——权限、认证源码分析、过滤、排序、分页的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?