DRF-Permission组件源码分析及改编源码
1. 权限组件源码分析
PS:下列源码为了方便理解都进行了简化,只保留了权限相关的代码



由于视图函数中继承了APIView,因此permission_classes可在视图类中进行重写。
注意点:
- 执行权限校验前,已执行了认证流程。因此此时可通过self.user获取用户对象(认证通过的情况)

2. 实践:编写一个权限类
假设我们在认证通过后,给每个用户对象都加上表示角色的属性role。1代表普通用户, 2代表经理, 3代表BOSS:
import random
from rest_framework.permissions import BasePermission
from rest_framework.request import Request
class UserPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 3:
return True
return False
class ManagerPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 2:
return True
return False
class BossPermission(BasePermission):
message = {"code": 1001, "detail": "无权限"} # 无权限时返回的信息
def has_permission(self, request, view):
if request.user.role == 1:
return True
return False
3. 源码改编
- 将权限校验中的“且”改为“或”关系,即只要有一个权限类通过校验即代表权限校验通过,继续执行后续代码:
# 在视图类中重写源码中的check_permissions方法:
def check_permissions(self, request):
no_permission_objects = [] # 未通过校验的权限对象
for permission in self.get_permissions():
if permission.has_permission(request, self):
# 只要有一个权限类通过校验则立即停止函数
return
else:
no_permission_objects.append(permission)
else: # 所有权限类都未通过校验
self.permission_denied(
request,
message=getattr(no_permission_objects[0], 'message', None),
code=getattr(no_permission_objects[0], 'code', None))
- 若想要所有视图类能使用该重写的功能,可将该方法单独写成类(MyAPIView),并继承APIView;其他要使用该重写方法的视图不再继承APIView,而是继承MyAPIView
# utils.py
class MyAPIView(APIView):
# 改写权限,变为"或"关系;
def check_permissions(self, request):
no_permission_objects = [] # 未通过校验的权限对象
for permission in self.get_permissions():
if permission.has_permission(request, self):
# 只要有一个权限类通过校验则立即停止函数
return
else:
no_permission_objects.append(permission)
else: # 所有权限类都未通过校验
self.permission_denied(
request,
message=getattr(no_permission_objects[0], 'message', None),
code=getattr(no_permission_objects[0], 'code', None))
# views.py
class UserView(APIView): # 继承DRF的APIView,则权限判断为“且”的关系
# 只有用户有权限
permission_classes = [UserPermission]
def get(self, request, pid):
return Response("hello get")
def post(self, request, pid):
return Response({"nihao post!"})
class OrderView(MyAPIView): # 用了自己改写的类MyAPIView,则权限判断为“或"的关系
# 经理和BOSS都有权限
permission_classes = [BossPermission, ManagerPermission]
def get(self, request, pid):
return Response("hello get")
def post(self, request, pid):
return Response({"nihao post!"})
DRF-Permission组件源码分析及改编源码的更多相关文章
- drf的基本使用、APIView源码分析和CBV源码拓展
cbv源码拓展 扩展,如果我在Book视图类中重写dispatch方法 -可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果 def dispatch(self, requ ...
- NIO 源码分析(05) Channel 源码分析
目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...
- NIO 源码分析(02-2) BIO 源码分析 Socket
目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...
- NIO 源码分析(02-1) BIO 源码分析
目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...
- [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast
[源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- k8s client-go源码分析 informer源码分析(3)-Reflector源码分析
k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...
- 5.2 spring5源码--spring AOP源码分析三---切面源码分析
一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...
- jQuery1.11源码分析(1)-----Sizzle源码概览[原创]
最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...
- 【MyBatis源码分析】select源码分析及小结
示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...
随机推荐
- 10-canva绘制数据点
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- 关于如何解决IDEA中同一个src下多个类中之一运行时自动报错其他类中的问题导致想要运行的类无法正常运行的问题的解决思路
关于如何解决IDEA中同一个src下多个类中之一运行时自动报错其他类中的问题导致想要运行的类无法正常运行的问题的解决思路 WrongFirst: 我准备了一个正常类BG和一个有错误的类HelloWor ...
- tar分段压缩导入
压缩 ll drwxrwxrwx 4 postgres postgres 20480 Oct 10 14:54 gitee-repo #分段压缩 tar czf - gitee-repo/ | spl ...
- 关于对 Tomcat 进行小版本升级的快速解决方案
1.背景描述 原来的 Tomcat 在部署时,使用的是最新的版本 9.0.40 . 经过一段时间后,在原来的 Tomcat 版本中,发现存在漏洞. 因此,需要将旧版本(9.0.40)升级到没有漏洞的新 ...
- Kubernetes 初学部署遇到的问题
### Kubernetes 部署文档(CentOS 7.9) 本文采用centos9 截至2024年8月21日官网已经不再提供其他下载 直接用最新版即可 1. CentOS 7.9 内核版本问题 截 ...
- Kubernetes-6:Pod生命周期介绍(init Container)
Pod生命周期 生命周期 1.API server调用kubelet下达Pod创建指令 2.容器环境初始化 3.进入Pod生命周期内(Pod开始创建) 4.Pod只要创建,就会自动生成一个pause容 ...
- C#/.NET/.NET Core优质学习资料,干货收藏!
前言 今天大姚给大家分享一些C#/.NET/.NET Core优质学习资料,希望可以帮助到有需要的小伙伴. 什么是 .NET? .NET 是一个免费的.跨平台的.开源开发人员平台,用于构建许多不同类型 ...
- Node.js开发博客项目笔记-搭建环境(2)
搭建环境 首先新建blog-1文件夹,在文件夹下初始化package.json,执行命令: npm init -y 生成的package.json文件中的main属性默认值index.js改成bin/ ...
- RxJS 系列 – Conditional and Boolean Operators
前言 前几篇介绍过了 Creation Operators Filtering Operators Join Creation Operators Error Handling Operators T ...
- JavaScript Library – PhotoSwipe
效果 前言 以前用过 lightbox2 和 fancyapps. lightbox2 已经没有维护了. fancyapps 改版好多次了. v2, v3 现在 v4 已经开始收费了. PhotoSw ...