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来说它就是 ...
随机推荐
- Codeforces Round 911 (Div. 2) D
Codeforces Round 911 (Div. 2) D D. Small GCD 题意 定义\(f(a,b,c)\)为\(a,b,c\)中较小两个数的\(gcd\),给定数组\(a_{1... ...
- .NET+WPF 桌面快速启动工具 GeekDesk
前言 大家在平时工作中,是不是经常为了找某个文件或者应用而在电脑桌面上来回翻找?桌面图标乱七八糟,每次找东西都像在大海捞针一样. 今天给大家介绍一个开源项目 GeekDesk,它能够让桌面焕然一新,工 ...
- Linux-centos中修改默认root帐户的登录用户名
vi /etc/passwd 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键退出编辑状态,并输入:x保存并退出 vi /etc/shadow 按i键进入编辑状态 修改第1行第1个 ...
- 痞子衡嵌入式:在IAR开发环境下将尽可能多的代码重定向到RAM中执行的方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将尽可能多的代码重定向到RAM中执行的方法. 最近和同事在讨论一个客户案例,客户 APP 工程是基于 IAR 开发环境 ...
- 我恨 gevent
报错了一晚上,最后发现是 python 版本不对.3.11,3.12,3.8,3.10 试了个遍,最后 3.10 终于编译通过了 还有这个 greenlet,每次都是它和 gevent 合着来恶心我 ...
- python 猜数字游戏(多版本)
原始版本 print('------------------你是sb------------------') temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:" ...
- win10自动更新导致的任务栏假死,右键单击任务栏延迟菜单延迟出现
系统是win10企业版,前天晚上回家之前,电脑还是好好的,然后前天早上跑过来以后,发现电脑自动重启了,我还以为是办公室停电了之类的(现在想了一下愚蠢,停电不会自动开机),没想到是自动更新 然后我发现, ...
- 同步多个mysql 到一个
了解大概 Ref: is it possible that canal set with multiple mysql database source 使用 canal https://dev.mys ...
- Word字体与像素的对应关系
英文字体的1磅(pt),相当于1/72 英寸(inch),约等于1/2.8mm.12PT的字打印出来约为4.2mm.网页中12px的字才相当于12像素. 虽然 四号=(14/72)*96=18.6px ...
- JSP——简介-快速入门
JSP 简介 JSP 快速入门 <%@ page contentType="text/html;charset=UTF-8" language=&qu ...