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组件源码分析及改编源码的更多相关文章

  1. drf的基本使用、APIView源码分析和CBV源码拓展

    cbv源码拓展 扩展,如果我在Book视图类中重写dispatch方法 -可以实现,在get,post方法执行之前或者之后执行代码,完成类似装饰器的效果 def dispatch(self, requ ...

  2. NIO 源码分析(05) Channel 源码分析

    目录 一.Channel 类图 二.begin 和 close 是什么 2.1 AbstractInterruptibleChannel 中的 begin 和 close 2.2 Selector 中 ...

  3. NIO 源码分析(02-2) BIO 源码分析 Socket

    目录 一.BIO 最简使用姿势 二.connect 方法 2.1 Socket.connect 方法 2.2 AbstractPlainSocketImpl.connect 方法 2.3 DualSt ...

  4. NIO 源码分析(02-1) BIO 源码分析

    目录 一.BIO 最简使用姿势 二.ServerSocket 源码分析 2.1 相关类图 2.2 主要属性 2.3 构造函数 2.4 bind 方法 2.5 accept 方法 2.6 总结 NIO ...

  5. [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast

    [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...

  6. Spring Ioc源码分析系列--Ioc源码入口分析

    Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...

  7. k8s client-go源码分析 informer源码分析(3)-Reflector源码分析

    k8s client-go源码分析 informer源码分析(3)-Reflector源码分析 1.Reflector概述 Reflector从kube-apiserver中list&watc ...

  8. 5.2 spring5源码--spring AOP源码分析三---切面源码分析

    一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...

  9. jQuery1.11源码分析(1)-----Sizzle源码概览[原创]

    最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...

  10. 【MyBatis源码分析】select源码分析及小结

    示例代码 之前的文章说过,对于MyBatis来说insert.update.delete是一组的,因为对于MyBatis来说它们都是update:select是一组的,因为对于MyBatis来说它就是 ...

随机推荐

  1. 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... ...

  2. .NET+WPF 桌面快速启动工具 GeekDesk

    前言 大家在平时工作中,是不是经常为了找某个文件或者应用而在电脑桌面上来回翻找?桌面图标乱七八糟,每次找东西都像在大海捞针一样. 今天给大家介绍一个开源项目 GeekDesk,它能够让桌面焕然一新,工 ...

  3. Linux-centos中修改默认root帐户的登录用户名

    vi /etc/passwd 按i键进入编辑状态 修改第1行第1个root为新的用户名 按esc键退出编辑状态,并输入:x保存并退出 vi /etc/shadow 按i键进入编辑状态 修改第1行第1个 ...

  4. 痞子衡嵌入式:在IAR开发环境下将尽可能多的代码重定向到RAM中执行的方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将尽可能多的代码重定向到RAM中执行的方法. 最近和同事在讨论一个客户案例,客户 APP 工程是基于 IAR 开发环境 ...

  5. 我恨 gevent

    报错了一晚上,最后发现是 python 版本不对.3.11,3.12,3.8,3.10 试了个遍,最后 3.10 终于编译通过了‍ 还有这个 greenlet,每次都是它和 gevent 合着来恶心我 ...

  6. python 猜数字游戏(多版本)

    原始版本 print('------------------你是sb------------------') temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:" ...

  7. win10自动更新导致的任务栏假死,右键单击任务栏延迟菜单延迟出现

    系统是win10企业版,前天晚上回家之前,电脑还是好好的,然后前天早上跑过来以后,发现电脑自动重启了,我还以为是办公室停电了之类的(现在想了一下愚蠢,停电不会自动开机),没想到是自动更新 然后我发现, ...

  8. 同步多个mysql 到一个

    了解大概 Ref: is it possible that canal set with multiple mysql database source 使用 canal https://dev.mys ...

  9. Word字体与像素的对应关系

    英文字体的1磅(pt),相当于1/72 英寸(inch),约等于1/2.8mm.12PT的字打印出来约为4.2mm.网页中12px的字才相当于12像素. 虽然 四号=(14/72)*96=18.6px ...

  10. JSP——简介-快速入门

    JSP 简介       JSP 快速入门       <%@ page contentType="text/html;charset=UTF-8" language=&qu ...