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——权限、认证源码分析、过滤、排序、分页的更多相关文章
- 断点调试/认证/权限/频率-源码分析/基于APIView编写分页/异常处理
内容概要 断点调试 认证/权限/频率-源码分析 基于APIView编写分页 异常处理 断点调试 # 程序以 debug模式运行,可以在任意位置停下,查看当前情况下变量数据的变化情况 # pycharm ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- drf-三大认证源码分析、基于APIView编写分页、异常处理
1.权限源码分析 1.APIView源码497行:self.initial(request, *args, **kwargs)中进行了三大认证. 2.在initial的源码中,以下三行代码是进行三大认 ...
- Django(64)频率认证源码分析与自定义频率认证
前言 有时候我们发送手机验证码,会发现1分钟只能发送1次,这是做了频率限制,限制的时间次数,都由开发者自己决定 频率认证源码分析 def check_throttles(self, request): ...
- Django(50)drf异常模块源码分析
异常模块源码入口 APIView类中dispatch方法中的:response = self.handle_exception(exc) 源码分析 我们点击handle_exception跳转,查看该 ...
- Django(48)drf请求模块源码分析
前言 APIView中的dispatch是整个请求生命过程的核心方法,包含了请求模块,权限验证,异常模块和响应模块,我们先来介绍请求模块 请求模块:request对象 源码入口 APIView类中di ...
- Django-restframework 之认证源码分析
Django-restframework 源码分析之认证 前言 最近学习了 django 的一个 restframework 框架,对于里面的执行流程产生了兴趣,经过昨天一晚上初步搞清楚了执行流程(部 ...
- Django(49)drf解析模块源码分析
前言 上一篇分析了请求模块的源码,如下: def initialize_request(self, request, *args, **kwargs): """ Retu ...
- Django(51)drf渲染模块源码分析
前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...
- drf认证源码分析
补充: 一.django中间件之路由斜杠的自动添加源码 其实我们每次在写路由的时候,如果在路由层给他设置的是加/,但实际上我们在浏览器中输入的时候并没有加/发现也能调用,前面说了是浏览器内部走了重定向 ...
随机推荐
- Salesforce LWC学习(二十) CLI篇:新版本不支持Audience解决方案
本篇参考:https://github.com/forcedotcom/cli/issues/470 https://developer.salesforce.com/docs/atlas.en-us ...
- Kafka 实现延迟队列、死信队列、重试队列
更多内容,访问 IT-BLOG Kafka中实现延迟队列 在发送延时消息的时候并不是先投递到要发送的真实主题(real_topic)中,而是先投递到一些 Kafka 内部的主题(delay_topic ...
- 如何提取 x64 程序那些易失的方法参数
一:背景 1. 讲故事 最近经常遇到有朋友反馈,在 x64 环境下如何提取线程栈中的方法参数,熟悉 x64 调用协定的朋友应该知道,这种协定范围下,方法的前四个参数都是用寄存器传递的,比如rcx,rd ...
- 重新编译Unity Mono遇到的坑,大坑,巨坑!!!
因为项目需要,要整一个DLL热更功能,本身也想对DLL进行加密,所以需要修改Mono的代码,并重新编译.参考了网上的教程后,决定在linux下做重编的工作. 然而在实际执行的时候,一开始就碰到了巨大的 ...
- [智能制造] 如何利用生产软件(MES)进行生产信息收集?
1 如何保证生产管理软件所收集信息的准确性? 1.1 当前制造企业使用MES系统收集信息的现状 原以为使用了MES生产管理系统后,会得到稽核员的肯定. 但没想到,在实际的稽核过程中,稽核员还是发现目前 ...
- [Linux]VMware启动CENOTS7时报"welcome to emergency mode!"【转载】
1 问题描述 由于通过VMwaer快速克隆了一台CENTOS7.9的虚拟机. 但启动时报如下错误信息 welcome to emergency mode!after logging in ,type ...
- 《花雕学AI》13:早出对策,积极应对ChatGPT带来的一系列风险和挑战
ChatGPT是一款能和人类聊天的机器人,它可以学习和理解人类语言,也可以帮人们做一些工作,比如翻译.写文章.写代码等.ChatGPT很强大,让很多人感兴趣,也让很多人担心. 使用ChatGPT有一些 ...
- Java设计模式 —— 外观模式
13 外观模式 13.1 外观模式概述 Facade Pattern: 为子系统的接口提供一组统一的入口.外观模式定义了一个高层接口,这个接口使得子系统的更加容易使用. 在外观模式中,一个子系统的外部 ...
- 【c#表达式树】最完善的表达式树Expression.Dynamic的玩法
引言 在我第一次写博客的时候,写的第一篇文章,就是关于表达式树的,链接:https://www.cnblogs.com/1996-Chinese-Chen/p/14987967.html,其中,当时一 ...
- 【前端基础】(二)promise异步编排
☆promise异步编排 javascript众所周知只能支持单线程,因此各种网络请求必须异步发送,导致可能会出现很多问题,比如如下我们有三个文件,现在要求进行如下请求: ① 查出当前用户信息 ② 根 ...