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 ...
随机推荐
- 聊聊Socket、TCP/IP、HTTP、FTP及网络编程
1 这些都是什么 既然是网络传输,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. 1.1 TCP ...
- Dashboard二次开发简明教程
Horizon简介 Horizon是OpenStack的一个子项目,用于提供一个Web前端控制台(称为Dashboard),以此来展示OpenStack的功能.通常情况下,我们都是从Horizon.D ...
- ACM——八大输出方式总结
个人做题总结,希望能够帮助到未来的学弟学妹们的学习! 永远爱你们的 ----新宝宝 1: 题目描述 Your task is to Calculate a + b. Too easy?! Of cou ...
- Postman----基础使用篇(没有接口文档的情况下如何着手做接口测试)
[备注说明]内文中的图片由于页面的限制,图片显示不清晰,为了能更加的看清图片,请点击"图片",点击"右键"选择"在新标签页中打开图片",可查 ...
- Python + Appium 获取当前屏幕的截图方法的封装
使用方法:get_screenshot_as_file(filename),来自于selenium\webdriver\remote\webdiver.py def take_screenShot(s ...
- [Active Learning] 01 A Brief Introduction to Active Learning 主动学习简介
目录 什么是主动学习? 主动学习 vs. 被动学习 为什么需要主动学习? 主动学习与监督学习.弱监督学习.半监督学习.无监督学习之间的关系 主动学习的种类 主动学习的一个例子 主动学习工具包 ALiP ...
- kolla 多节点部署 openstack
kolla 介绍 简介 kolla 的使命是为 openstack 云平台提供生产级别的.开箱即用的交付能力.kolla 的基本思想是一切皆容器,将所有服务基于 Docker 运行,并且保证一个容器只 ...
- 为什么面试你要25K,HR只给你20K?
周末了,我们来聊个轻松的话题,关于涨薪,哈哈~ 前阵子,栈长给大家分享了<为什么公司宁愿 25K 重新招人,也不给你加到 20K?>,今天我们来聊一个差不多的话题: 为什么面试你要25K, ...
- redis的set类型!!!!
一.概述 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复杂度为 ...
- java游戏开发杂谈 - 画布和画笔
在Eclipse里,编写如下两个类: package game2; import java.awt.Color; import java.awt.Graphics; import javax.swin ...