Django-restframework 之权限源码分析
Django-restframework 之权限源码分析
一 前言
上篇博客分析了 restframework 框架的认证组件的执行了流程并自定义了认证类。这篇博客分析 restframework 的权限组件执行流程。入口函数依然是APIView.initial。
权限的判断是在用户认证之后进行的,restframework 框架里面的自带的认证实现的功能很简单,如下:

这个方法通常来讲会根据需求定制,该方法执行结束后悔返回用户信息和其他数据,根据需求,在上篇博客我返回了用户对象和 token 值。

本来这些应该在上篇博客结束的,主要是因为今天学习权限组件时又想到有些遗漏所以在这里补充。
二 权限组件执行流程
APIView.perform_authentication()方法结束,其实是根据mro列表找到的。接下来执行APIView.check_permissions()方法,restframework 框架自带的权限类相当于没有,因为所有需要进行权限认证的都是返回 True,所以这个也需要根据实际需求来定制。
1. 执行 APIView.check_permissions
其实套路和认证组件很相似

2. 执行APIView.get_permission

对比权限和认证的查找相关类的流程可以发现认证类是在实例化Request对象时就把认证类获取当作参数传进去了,而权限类并没有。猜测 restframework 框架只要需要进行用户认证,所以虽然认证写的功能也不完善,但是还是必要的,而权限相关的认证和实际需求有关,所以就没有这么麻烦,猜测频率也一样,也需要自己重写和配置。
3. 执行APIView.permission_classes

经过这几步就可以找到权限类
三 自定义权限组件
其实基本步骤和认证组件一样
1. views.py
from app01 import permiss_classes
2. permiss_classes.py
from rest_framework.permissions import BasePermission
class LoginPermission(BasePermission):
def has_permission(self, request, view):
print(request.user, 'guanjian')
user = request.user
if user.user_type == 1:
return True
return False
3. 使用
只要用户权限满足才能获取相关信息,所以在用户表中加了个字段用来标识用户权限的
# models.py
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
password = models.CharField(max_length=32)
age = models.IntegerField()
gender = models.SmallIntegerField()
book = models.ManyToManyField(to='Book', through='User2Book', through_fields=('user', 'book'))
user_choice = ((0, '封禁用户'), (1, '普通用户'), (2, '超级用户'))
user_type = models.IntegerField(default=0, choices=user_choice)
完整的 models.py
from django.db import models
# Create your models here.
# book_obj.author.set(*[])
# class UserToken(models.Model):
# nid = models.AutoField(primary_key=True)
# user = models.OneToOneField(to='UserInfo', default=1)
# token = models.CharField(max_length=64, default='123456')
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
password = models.CharField(max_length=32)
age = models.IntegerField()
gender = models.SmallIntegerField()
book = models.ManyToManyField(to='Book', through='User2Book', through_fields=('user', 'book'))
user_choice = ((0, '封禁用户'), (1, '普通用户'), (2, '超级用户'))
user_type = models.IntegerField(default=0, choices=user_choice)
def __str__(self):
return self.name
class Meta:
verbose_name = '用户表'
verbose_name_plural = verbose_name
# 用户拥有的图书表,因为是多对多关系,所以是中间表
class User2Book(models.Model):
nid = models.AutoField(primary_key=True)
user = models.ForeignKey(to='UserInfo')
book = models.ForeignKey(to='Book')
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.IntegerField()
publish = models.ForeignKey(to='Publish', to_field='nid')
pub_date = models.DateTimeField(auto_now_add=True)
author = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))
def __str__(self):
return self.name
class Meta:
verbose_name = '图书表'
verbose_name_plural = verbose_name
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
email = models.EmailField()
class Meta:
verbose_name = '出版社表'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
phone = models.CharField(max_length=32, default=15764503613)
class Meta:
verbose_name = '作者表'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Book2Author(models.Model):
nid = models.AutoField(primary_key=True)
book = models.ForeignKey(to='Book', to_field='nid')
author = models.ForeignKey(to='Author', to_field='nid')
class Meta:
verbose_name = '图书作者表'
verbose_name_plural = verbose_name
四 配置自定义权限类
1. 局部配置
假设在用户认证通过后需要判断用户的权限,那么需要在该视图类中定义一个参数permission_classes
class Book(APIView):
authentication_classes = [authticate_classes.BookAuth]
permission_classes = [permiss_classes.LoginPermission]
# authentication_classes = []
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request, id):
print(request.user, '444')
response = {'status': 100, 'msg': None}
book_obj = models.Book.objects.filter(pk=id).first()
if book_obj:
book_ser = myser.BookSer(book_obj, many=False)
response['book'] = book_ser.data
else:
response['msg'] = '图书没有对象'
response['status'] = 101
return Response(response)
2. 全局使用
全局使用的话需要在项目的 settings 中配置,如下:
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES': ['app01.permiss_classes.LoginPermission']
}
3. 局部禁用
局部禁用需要在视图类中定义一个空的permission_classes
permission_classes = []
Django-restframework 之权限源码分析的更多相关文章
- Django(63)drf权限源码分析与自定义权限
前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...
- django的RestFramework模块的源码分析
一.APIView源码分析 查看源码的前提要知道,找函数方法必须先在自己的类中找,没有再往父类找,一层一层网上找,不能直接按ctrl点击 在我们自己定义的类中没有as_view方法的函数,所以肯定是继 ...
- Django之REST framework源码分析
前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...
- Python学习---Django的request.post源码分析
request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去
- Django 之 restframework 解析器源码分析
解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...
- Django rest framework 版本控制(源码分析)
基于上述分析 #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制 self.initial(request, *args, **kwargs) #2.1处理版本信息 #versi ...
- Django _VIEW视图_源码分析
Django _VIEW视图: 1. 点击as_view方法. 第二步: as_view () 为VIEW 类里定义的,到时候我们定义业务逻辑的类就继承这个VIEW类. view方法内返回的是disp ...
- Django之CBV视图源码分析(工作原理)
1.首先我们先在urls.py定义CBV的路由匹配. FBV的路由匹配: 2.然后,在views.py创建一名为MyReg的类: 注意:该类必须继续View类,且方法名必须与请求方式相同(后面会详解) ...
- Django中间件之SessionMiddleware源码分析
settings.py文件中 MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', ] # from djang ...
随机推荐
- BZOJ_1827_[Usaco2010 Mar]gather 奶牛大集会_树形DP
BZOJ_1827_[Usaco2010 Mar]gather 奶牛大集会_树形DP 题意:Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来 ...
- iOS指纹识别Touch ID的安全性探讨
苹果公司在 iPhone 5s 的发布会上公布了全新的指纹识别安全技术,也就是 Touch ID,开创了生物安全识别技术在便携设备上使用的新篇章.此后,苹果还将此技术带到了 iPad 上.此前没有任何 ...
- CSS 盒模型与box-sizing
一.盒模型 一个web页面由许多html元素组成,而每一个html元素都可以表示为一个矩形的盒子,CSS盒模型正是描述这些矩形盒子的存在. MDN的描述: When laying out a docu ...
- 频率学派与贝叶斯学派(先验分布与后验分布,MLE和MAP)
频率学派(古典学派)和贝叶斯学派是数理统计领域的两大流派. 这两大流派对世界的认知有本质的不同:频率学派认为世界是确定的,有一个本体,这个本体的真值是不变的,我们的目标就是要找到这个真值或真值所在的范 ...
- 一致性 Hash 算法的实际应用
前言 记得一年前分享过一篇<一致性 Hash 算法分析>,当时只是分析了这个算法的实现原理.解决了什么问题等. 但没有实际实现一个这样的算法,毕竟要加深印象还得自己撸一遍,于是本次就当前的 ...
- 【RecyclerView优化】
1.局部刷新 (1)避免整个列表的数据更新,只更新受影响的布局.例如,加载更多时,不使用notifyDataSetChanged(),而是使用notifyItemRangeInserted(range ...
- Asp.NetCore轻松学-部署到 Linux 进行托管
前言 上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS,且学习了进程内托管和进程外托管的区别:接下来就要说说应用 Asp.Net Core 的特性(跨平台),将 .Ne ...
- 如何在CentOS上创建Kubernetes集群
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由编程男孩 发表于云+社区专栏 介绍 Kubernetes(常简称为K8s)是用于自动部署.扩展和管理容器化(containerized ...
- Java实现文本编辑时基于拼音输入的补全原型
续前文Java实现"命令式"简易文本编辑器原型. 效果如下: 所在源码库同上文, 尚未和上文的编辑器右侧的命令区集成. 代码由How to show autocomplete as ...
- 2017-12-09 JavaScript实现ZLOGO子集: 测试用例
续前文JavaScript实现ZLOGO子集: 前进+转向. 在添加新功能之前, 先添加测试用例, 以应对日益复杂的代码. 选择使用QUnit编写运行测试用例. 暂时对比较复杂和I/O无关的部分进行测 ...