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 之权限源码分析的更多相关文章

  1. Django(63)drf权限源码分析与自定义权限

    前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...

  2. django的RestFramework模块的源码分析

    一.APIView源码分析 查看源码的前提要知道,找函数方法必须先在自己的类中找,没有再往父类找,一层一层网上找,不能直接按ctrl点击 在我们自己定义的类中没有as_view方法的函数,所以肯定是继 ...

  3. Django之REST framework源码分析

    前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...

  4. Python学习---Django的request.post源码分析

    request.post源码分析: 可以看到传递json后会帮我们dumps处理一次最后一字节形式传递过去

  5. Django 之 restframework 解析器源码分析

    解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...

  6. Django rest framework 版本控制(源码分析)

    基于上述分析 #2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制 self.initial(request, *args, **kwargs) #2.1处理版本信息 #versi ...

  7. Django _VIEW视图_源码分析

    Django _VIEW视图: 1. 点击as_view方法. 第二步: as_view () 为VIEW 类里定义的,到时候我们定义业务逻辑的类就继承这个VIEW类. view方法内返回的是disp ...

  8. Django之CBV视图源码分析(工作原理)

    1.首先我们先在urls.py定义CBV的路由匹配. FBV的路由匹配: 2.然后,在views.py创建一名为MyReg的类: 注意:该类必须继续View类,且方法名必须与请求方式相同(后面会详解) ...

  9. Django中间件之SessionMiddleware源码分析

    settings.py文件中 MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', ] # from djang ...

随机推荐

  1. 回归树(Regression Tree)

    目录 回归树 理论解释 算法流程 ID3 和 C4.5 能不能用来回归? 回归树示例 References 说到决策树(Decision tree),我们很自然会想到用其做分类,每个叶子代表有限类别中 ...

  2. 客户端热更新框架之UI热更框架设计(上)

    什么是热更新,为什么需要热更新?          热更新是目前各大手游等众多App常用的更新方式.简单来说就是在用户通过App Store下载App之后,打开App时遇到的即时更新.对于手游客户端来 ...

  3. volitale、synchronized、RetreenLock区别

    synchronized和RetreenLock锁区别 1.synchronized是java关键字,RetreenLock是个java类 2.synchronized无法获取锁状态,Lock可以判断 ...

  4. 跟我一起学opencv 第四课之图像的基本操作

    1.图像是由像素组成的,所以修改了像素就可以实现图像的改变. 2先看灰度图像(单通道): *****2.获取灰度图像的像素值使用:  int gray = gray_src.at<uchar&g ...

  5. mariaDB vs mysql

    mariaDB vs mysql 今天遇到一个库使用的是mariaDB的数据库版本 Server version: 10.1.20-MariaDB MariaDB Server 理了一下mariaDB ...

  6. C# 通俗说 哈希表

    1.何谓哈希 哈希,也程散列.哈希表是一种与数组,链表等不同的数据结构,与他们需要不断的 遍历比较查找的办法,哈希表设计了一个映射关系发f(key)=adress,根据key来计算adress, 这样 ...

  7. Java:基于MD5的文件监听程序

    前述和需求说明 和之前写的 Python:基于MD5的文件监听程序 是同样的功能,就不啰嗦了,就是又写了一个java版本的,可以移步 python 版本去看一下,整个的核心思路是一样的.代码已上传Gi ...

  8. Python:requests:详解超时和重试

    网络请求不可避免会遇上请求超时的情况,在 requests 中,如果不设置你的程序可能会永远失去响应.超时又可分为连接超时和读取超时. 连接超时 连接超时指的是在你的客户端实现到远端机器端口的连接时( ...

  9. C#操作符??,?,?:功能解析

    ??操作符:叫做空合并操作符,它会对左右两个操作数进行判断,如果左边的数不为空,就返回左边的数,否则返回右边的数. ?操作符:语法糖,表示可空类型,可空类型也是值类型,它是包含null值的值类型,可通 ...

  10. USB总线标准

    1.USB总线类型: OHCI(Open Host Controller Interface)是支持USB1.1的标准,但它不仅仅是针对USB,UHCI(Universal Host Controll ...