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. BZOJ_3262_陌上花开_CDQ分治+树状数组

    BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...

  2. linux学习之路(1)

    Linux基础命令 命令格式:   命令名称  [参数]  [对象] 命令参数的长格式与短格式: 长格式:man -- help 短格式:man - h 常用系统工作命令 echo     输出语句  ...

  3. Error【0002】:YUM本地源配置问题

    1.1 问题背景 通过VMware workstation创建虚拟机,在虚拟机的CDROM设备中,装载操作系统镜像.然后通过mount -o loop的方式,将CDROM设备挂载到系统的/mnt/cd ...

  4. html select 标签设置默认选中

    方法有两种. 第一种通过<select>的属性来设置选中项,此方法可以在动态语言如php在后台根据需要控制输出结果. 1 2 3 4 5 < select  id =  " ...

  5. MySQL 上手教程

    安装 通过官网选择版本下载安装.Mac 上可通过 Homebrew 方便地安装: $ brew install mysql 检查安装是否成功: $ mysql --version mysql Ver ...

  6. Python练习:关于递归的经典实例设计

    (一)裴波拉契数列 利用递归算法获得裴波拉契数列前N个值的结果: #裴波拉契数列,通过递归计算 def fb(n): if n <=0: res = 0 elif n ==1: res = 1 ...

  7. API做翻页的两种思路

    在开发API的时候,有时候数据太多了,就需要分页读取. 基于偏移量的分页(Offset-based) 这种方式就是会提供一个每页笔数(page size)来定义返回条目的最大数,提供一个页数(page ...

  8. Python:基于MD5的文件监听程序

    前述 写了一个基于MD5算法的文件监听程序,通过不同的文件能够生成不同的哈希函数,来实现实现判断文件夹中的文件的增加.修改.删除和过滤含有特定字符的文件名的文件. 需求说明 需要实现对一个文件夹下的文 ...

  9. Java进阶篇设计模式之十三 ---- 观察者模式和空对象模式

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  10. Flutter 实现原理及在马蜂窝的跨平台开发实践

    一直以来,跨平台开发都是困扰移动客户端开发的难题. 在马蜂窝旅游 App 很多业务场景里,我们尝试过一些主流的跨平台开发解决方案, 比如 WebView 和 React Native,来提升开发效率和 ...