Django rest_framework-权限组件

[TOC]

一、权限组件的使用

# 用户信息表
class UserInfo(models.Model):
name = models.CharField(max_length=32)
# 写choice
user_choice=((0,'普通用户'),(1,'会员'),(2,'超级用户'))
# 指定choice,可以快速的通过数字,取出文字
user_type=models.IntegerField(choices=user_choice,default=0)
pwd = models.CharField(max_length=32) # 用户token
class UserToken(models.Model):
token = models.CharField(max_length=64)
user = models.OneToOneField(to=UserInfo)

1、使用语法

from rest_framework.permissions import BasePermission

# 写一个权限类
class UserPermission(BasePermission):
# 重写没有权限时的数据
message = '您没有权限'
# 重写has_permission()方法,传入三个参数
# 第一个是对象自身(自动传);第二个是request对象;第三个是
def has_permission(self, request, view):
# 只要认证通过,就会把当前用户对象放到request中
user_type = request.user.user_type
# get_字段名_display() 可以获取choice数字对应的具体值
# user_type_name = request.user.get_user_type_display()
# print(user_type_name)
if user_type == 2:
return True
return False
class Book(APIView):
# 用户认证
authentication_classes = [UserAuth.UserAuth, ]
# 权限判断
permission_classes = [MyPerm.UserPermission, ] def get(self, request, *args, **kwargs):
response = {'status': 100, 'msg': '查询成功'}
ret = models.Book.objects.all()
ser = MySerializer.BookSerializer(instance=ret, many=True)
response['data'] = ser.data
return JsonResponse(response, safe=False)

2、全局使用、局部使用、局部禁用权限

(1)全局使用

  • 在settings文件中配置,配置完以后,就无需在视图类中写,已经是所有视图类都需要权限判断
  • 必须为REST_FRAMEWORK,key值必须为DEFAULT_AUTHENTICATION_CLASSES
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES':['app01.MyPerm.UserPermission',],
}

(2)局部使用

在需要使用的视图类中写,只对当前视图类起认证作用,重新定义permission_classes

class Book(APIView):
# # 该方法是局部使用认证
authentication_classes = [UserAuth.UserAuth, ]
# 该方法是局部使用权限
permission_classes = [MyPerm.UserPermission, ] def get(self, request, *args, **kwargs):
response = {'status': 100, 'msg': '查询成功'}
ret = models.Book.objects.all()
ser = MySerializer.BookSerializer(instance=ret, many=True)
response['data'] = ser.data
return JsonResponse(response, safe=False)

(3)局部禁用

在配置过全局权限判断以后,有些视图类不需要判断权限,可以局部禁用权限证,只需将permission_classes定义为空列表即可。

class Book(APIView):
# # 该方法是局部使用认证
authentication_classes = [UserAuth.UserAuth, ]
# 该方法是局部禁用权限
permission_classes = [] def get(self, request, *args, **kwargs):
response = {'status': 100, 'msg': '查询成功'}
ret = models.Book.objects.all()
ser = MySerializer.BookSerializer(instance=ret, many=True)
response['data'] = ser.data
return JsonResponse(response, safe=False)

二、源码分析

as_view ----------> view -------------> dispatch -------> Request包装新的request ------> 认证、权限、频率 --------> 根据请求方式分发到不同的方法

url(r'books/',views.Book.as_view())

1、Book中没有as_view

2、APIView的as_view

class APIView(View):

	@classmethod
# cls 是 Book类
def as_view(cls, **initkwargs): # view = super(APIView, Book).as_view(**initkwargs)
view = super(APIView, cls).as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs # Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)

3、view = super(APIView, cls).as_view(**initkwargs) ---------------------> View中的as_view

class View(object):

	@classonlymethod
# cls====> Book
def as_view(cls, **initkwargs): def view(request, *args, **kwargs):
# 实例化产生一个book对象
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
# 调dispatch方法
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view

4、return self.dispatch(request, *args, **kwargs) ----------------> dispatch

self====> Book对象,一层层找dispatch

APIView中找到dispatch

class APIView(View):

	def dispatch(self, request, *args, **kwargs):

        self.args = args
self.kwargs = kwargs # (a)初始化request,就是通过Request类来包装原生request,得到包装后的request
request = self.initialize_request(request, *args, **kwargs)
# 从现在开始request就是包装后的request
self.request = request
self.headers = self.default_response_headers # deprecate? try:
# (b) 认证、权限、频率
self.initial(request, *args, **kwargs) # Get the appropriate handler method
# http_method_names表示列表['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

(a)request = self.initialize_request(request, *args, **kwargs) 包装 request

self 是Book对象

class APIView(View):
# 默认的认证列表类
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
# (a-b)实例化初始化产生新的request对象
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), # 认证类实例化产生的对象的列表
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
    def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes]
(a------1)return Request( ··· ) ----------> Request类初始化
    def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), (
'The `request` argument must be an instance of '
'`django.http.HttpRequest`, not `{}.{}`.'
.format(request.__class__.__module__, request.__class__.__name__)
) self._request = request
self.parsers = parsers or ()
self.authenticators = authenticators or ()
self.negotiator = negotiator or self._default_negotiator()
self.parser_context = parser_context
self._data = Empty
self._files = Empty
self._full_data = Empty
self._content_type = Empty
self._stream = Empty if self.parser_context is None:
self.parser_context = {}
self.parser_context['request'] = self
self.parser_context['encoding'] = request.encoding or settings.DEFAULT_CHARSET force_user = getattr(request, '_force_auth_user', None)
force_token = getattr(request, '_force_auth_token', None)
if force_user is not None or force_token is not None:
forced_auth = ForcedAuthentication(force_user, force_token)
self.authenticators = (forced_auth,)

(b)self.initial(request, *args, **kwargs) -----> 认证、权限、频率

    def initial(self, request, *args, **kwargs):
"""
Runs anything that needs to occur prior to calling the method handler.
"""
self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request
neg = self.perform_content_negotiation(request)
request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted
# (b------1) 认证
self.perform_authentication(request)
# (b------2)权限
self.check_permissions(request)
# 频率
self.check_throttles(request)
(b------1) self.check_permissions(request) -------> 权限判断
    def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
# (b------1---------1) get_permissions 权限类对象组成的列表
for permission in self.get_permissions():
# 重写的就是这个has_permission()方法,判断当前用户是否有权限
if not permission.has_permission(request, self):
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
(b------1---------1) self.get_permissions() -------> 获取权限类对象组成的列表
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]

Django框架(二十一)—— Django rest_framework-权限组件的更多相关文章

  1. Django框架 之 admin管理工具(组件使用)

    Django框架 之 admin管理工具(组件使用) 浏览目录 激活管理工具 使用管理工具 admin的定制 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理 ...

  2. django框架<二>

    django框架:   Models 1.基本创建 Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据. Django使用一种新的方式,即:关系对象映射 ...

  3. Django框架(十四)-- forms组件、局部钩子、全局钩子

    一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...

  4. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  5. Django框架(十五)—— forms组件、局部钩子、全局钩子

    目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...

  6. Django框架(二) MTV模型简介

    MTV模型 Django的MTV分别代表 Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM) Template(模板):放所有的html文件 模板语法:目的是将白变量(数据库的内 ...

  7. Django框架(二)

    一:Django项目创建步骤: 方式1:命令创建: 进入指定目录 C:\Users\bing>F: F:\>cd mysite F:\mysite>django-admin star ...

  8. Django框架(十一)--cookie和session

    cookie和session组件 cookie 1.cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它 ...

  9. Django框架(十一)—— 常用字段、参数、元信息、多对多关联关系

    目录 常用字段和参数 一.ORM字段 二.ORM参数 三.关系字段 1.ForeignKey 2.OneToOneFiled 3.ManyToManyField 四.元信息 五.多对多关联关系的三种方 ...

  10. Django框架(十一)-- 补充:inclusion_tag、defer、only、choice、事务、创建多对多的第三张表、mvc和mtv模式

    一.inclusion_tag 1.作用 用于生成HTML片段,是数据由参数传入而变成动态 2.使用 # 1.app下新建一个模块,templatetags # 2.创建一个py文件(mytag.py ...

随机推荐

  1. 2019杭电多校第⑨场B Rikka with Cake (主席树,离散化)

    题意: 给定一块n*m的矩形区域,在区域内有若干点,每个顶点发出一条射线,有上下左右四个方向,问矩形被分成了几个区域? 思路: 稍加观察和枚举可以发现,区域数量=射线交点数+1(可以用欧拉定理验证,但 ...

  2. T1387:搭配购买(buy)

    [题目描述] Joe觉得云朵很美,决定去山上的商店买一些云朵.商店里有n朵云,云朵被编号为1,2,…...,n,并且每朵云都有一个价值.但是商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这朵 ...

  3. js设置cookies

    //写入cookies的方法 function setCookie(name, value, seconds) { seconds = seconds || 0; //seconds有值就直接赋值,没 ...

  4. Fatal Error -26000: Not enough memory (12320 bytes) for “new buffer in LrwSrvNetTaskIt 问题解决及lr脚本心得

    Fatal Error -26000: Not enough memory (12320 bytes) for “new buffer in LrwSrvNetTaskIt 问题解决及lr脚本心得 2 ...

  5. java反射(一)--认识反射机制

    一.认识java反射机制 在java语言中,之所以会有如此众多的开源技术支撑,很大的一部分来源于java最大特征--反射机制.能够灵活的去使用反射机制进行项目的开发与设计,才能够真正接触到java的精 ...

  6. 在Emacs中使用plantuml画UML图

    在Emacs中使用plantuml画UML图 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #83 ...

  7. 排列组合( Lindström–Gessel–Viennot lemma 定理)

    链接:https://www.nowcoder.com/acm/contest/139/A来源:牛客网 Monotonic Matrix 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ ...

  8. 通过yum在CentOS7部署LNMP环境(Centos7.4+Nginx1.12+mariadb5.5.56+PHP7.0)

    LNMP环境 CentOS Linux release 7.4.1708 PHP 7.0.25 nginx version: nginx/1.12.2 mariadb: 5.5.56-MariaDB ...

  9. MyEclipse2017搭建android开发环境

    1 安装MyEclipse2017cli7; 2 准备安装ADT插件和 Android SDK 开发包;比如:ADT-24.0.2 android-sdk_r24.4.1-windows; 工具栏点击 ...

  10. JavaScript值传递和引用传递

    1、数据类型:boolean,null,undefined,String,Number,指向包含的数据,进行“值传递”: 2.非数据类型:Array,Function,Object,指向了一个内存地址 ...