Django框架(二十)-- Django rest_framework-权限组件
一、权限组件的使用
# 用户信息表
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-权限组件的更多相关文章
- Django框架(十四)-- forms组件、局部钩子、全局钩子
一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...
- Django框架(十五)—— forms组件、局部钩子、全局钩子
目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...
- Django框架 之 admin管理工具(组件使用)
Django框架 之 admin管理工具(组件使用) 浏览目录 激活管理工具 使用管理工具 admin的定制 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理 ...
- 微信小程序把玩(二十八)image组件
原文:微信小程序把玩(二十八)image组件 image组件也是一个程序不可缺少的,可以这样说一个app中image组件随处可以看到,一般 image有两种加载方式第一种是网络图片第二种是本地图片资源 ...
- 微信小程序把玩(二十九)video组件
原文:微信小程序把玩(二十九)video组件 视频播放组件与图片加载组件也没啥差别,使用起来也没啥注意的 重要属性: wxml <!--监听button点击事件--> <button ...
- 微信小程序把玩(二十四)toast组件
原文:微信小程序把玩(二十四)toast组件 toast消息提示框,可用在提示一些信息,比如清楚缓存给用户一个友好的提示!或操作一些请求不想让用户有什么操作,toast也可以做到因为toast显示时其 ...
- 微信小程序把玩(二十五)loading组件
原文:微信小程序把玩(二十五)loading组件 loading通常使用在请求网络数据时的一种方式,通过hidden属性设置显示与否 主要属性: wxml <!----> <butt ...
- 微信小程序把玩(二十六)navigator组件
原文:微信小程序把玩(二十六)navigator组件 navigator跳转分为两个状态一种是关闭当前页面一种是不关闭当前页面.用redirect属性指定. 主要属性: wxml <naviga ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
- Django框架(十)--ORM多对多关联关系三种创建方式、form组件
多对多的三种创建方式 1.全自动(就是平常我们创建表多对多关系的方式) class Book(models.Model): title = models.CharField(max_length=32 ...
随机推荐
- Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib
1.目前Python版本管理工具有很多,pyenv是比较好用的一款,安装如下: 输入: git clone https://github.com/pyenv/pyenv.git ~/.pyenv ec ...
- jdk的一条命令查看运行参数
jps 查看运行的java进程; jinfo <pid> 查看 jvm 配置参数
- MNIST手写数字识别进阶:多层神经网络及应用(1)
# 一.载入数据 import tensorflow as tf import numpy as np #导入tensorflow提供的读取MNIST的模块 import tensorflow.exa ...
- Python企业面试题(系列目录)
本系列计划把Python面试中出现频率比较高知识点整理出来,以便各位童鞋复习和练习: [第1题] Python内存管理以及垃圾回收机制 [第2题] 链表的逆置 [第3题] 两个队列创建一个栈 [第4题 ...
- 鲜贝7.3--mysql安装
1.安装包下载 首先是下载 mysql-installer-community-5.6.14.0.msi ,大家可以到 mysql 官方网去下载. win10的安全机制比较严格,安装前最好到<设 ...
- Python进阶-XVIV 类的内置方法:__str__ 、__repr__、析构函数(__del__)、双下的call,eq,new,hash 以及item相关的三个方法
类的内置方法 它与内置函数有紧密的联系,有的内置函数就是调用的内置方法. 在顶级父类obj中有: 两个双下方法 obj.__str__ str(obj) obj.__repr__ repr(obj) ...
- 【PL/SQL】设置F8自动运行
- gradle是什么
Gradle是JVM生态下又一款开源的自动化构建工具,以基于Groovy的DSL描述构建过程,在结合了ant和maven的优点的基础上,提供了更为简洁,灵活和高效的build体验. Task代表了构建 ...
- ubuntu 查看版本
cat /etc/proc 可以查看是16.04还是18.04
- IPv6地址编址