一、权限组件的使用

# 用户信息表
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 Fals
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 ------> 认证、权限、频率 --------> 根据请求方式分发到不同的方法

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框架(十四)-- forms组件、局部钩子、全局钩子

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

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

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

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

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

  4. 微信小程序把玩(二十八)image组件

    原文:微信小程序把玩(二十八)image组件 image组件也是一个程序不可缺少的,可以这样说一个app中image组件随处可以看到,一般 image有两种加载方式第一种是网络图片第二种是本地图片资源 ...

  5. 微信小程序把玩(二十九)video组件

    原文:微信小程序把玩(二十九)video组件 视频播放组件与图片加载组件也没啥差别,使用起来也没啥注意的 重要属性: wxml <!--监听button点击事件--> <button ...

  6. 微信小程序把玩(二十四)toast组件

    原文:微信小程序把玩(二十四)toast组件 toast消息提示框,可用在提示一些信息,比如清楚缓存给用户一个友好的提示!或操作一些请求不想让用户有什么操作,toast也可以做到因为toast显示时其 ...

  7. 微信小程序把玩(二十五)loading组件

    原文:微信小程序把玩(二十五)loading组件 loading通常使用在请求网络数据时的一种方式,通过hidden属性设置显示与否 主要属性: wxml <!----> <butt ...

  8. 微信小程序把玩(二十六)navigator组件

    原文:微信小程序把玩(二十六)navigator组件 navigator跳转分为两个状态一种是关闭当前页面一种是不关闭当前页面.用redirect属性指定. 主要属性: wxml <naviga ...

  9. Django框架(十二)-- 中间件、CSRF跨站请求伪造

    中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...

  10. Django框架(十)--ORM多对多关联关系三种创建方式、form组件

    多对多的三种创建方式 1.全自动(就是平常我们创建表多对多关系的方式) class Book(models.Model): title = models.CharField(max_length=32 ...

随机推荐

  1. appium---adb logcat 命令详解

    我们在做app测试的过程中,肯定会遇到需要抓取日志问题,这几天安静也遇到了此问题,后台日志生成的太多了,保存本地了吧,设备多没有这么USB,通过wifi连接又太麻烦,你说这怎么是好?不要着急,我们往下 ...

  2. kettle教程---增量更新

    以下操作都在5.0.1版本下进行开发,其余版本可以进行自动比对 在平时工作当中,会遇到这种情况,而且很常见.比如:增量抽取(每隔2个小时抽取截至到上次抽取时间的记录) 一.操作前提: 存在3张表,源表 ...

  3. 5. Vue - 小清单实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. c# WF 第7节 对控件的基本操作

    本节内容: 1:修改控件的大小 2:控件的顺序 3:控件的对齐 4:移动button实例 1: 修改控件的大小 第一种: 第二种 : 一次操作多个控件: 选择一个控件.按住ctrl -- 再选择一个控 ...

  5. 17. 抽象建模能力&发散思维能力&综合(5)

    抽象建模能力 题一:[扑克牌顺子] LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽 ...

  6. 第05组团队Github现场编程实战

    第05组团队Github现场编程实战 一.组员职责分工 组员 分工 卢欢(组长) 前后端接口设计 严喜 寻找相关资料 张火标 设计并描述界面原型 钟璐英 编写随笔 周华 填写完善文档 古力亚尔·艾山 ...

  7. ASP.NET开发实战——(八)ASP.NET MVC 与数据库之MySQL

    之前介绍了My Blog如何使用ADO.NET来访问SQL Server获取数据.本章将介绍如何使用My SQL来完成数据管理. 在使用My SQL之前需确保开发环境中安装了My SQL数据库和Con ...

  8. jenkins配置自动部署java程序

    任务背景 该项目包含4个程序包:a.jar,b.jar,c.jar,d.jar,每次启动前需要修改程序中的配置文件(修改数据源配置),然后按照先后顺序启动. 任务目标 1.利用jenkins拉取代码, ...

  9. P2186 小Z的函数栈

    有点恶心的模拟(代码写整齐一点不就好了) 以下情况算错: 1.运行中有数的绝对值大于1000000000 2.除以和取模的时候第一个数为0 3.取栈顶元素时栈内元素不够 上代码 #include< ...

  10. A1029 Median (25 分)

    一.技术总结 最开始的想法是直接用一个vector容器,装下所有的元素,然后再使用sort()函数排序一下,再取出中值,岂不完美可是失败了,不知道是容器问题还是什么问题,就是编译没有报错,最后总是感觉 ...