【DRF-05】rest-framework之权限
- 1.需求:订单信息必须是SVIP用户才能查看
- 2.基本使用
- 2.1:models.py
from django.db import models
class UserInfo(models.Model):
user_type_choices = (
(1,'普通用户'),
(2,'VIP'),
(3,'SVIP'),
)
user_type = models.IntegerField(choices=user_type_choices)
username = models.CharField(max_length=32,unique=True)
password = models.CharField(max_length=64)
class UserToken(models.Model):
user = models.OneToOneField(to='UserInfo',on_delete=models.CASCADE)
token = models.CharField(max_length=64)
- 2.2:自定义权限类
from rest_framework.permissions import BasePermission
class SVIPPermission(BasePermission):
message = "必须是SVIP才能访问"
def has_permission(self,request,view):
if request.user.user_type != 3:
return False
return True
- 2.3:设置全局使用
REST_FRAMEWORK = {
# 全局使用的认证类
"DEFAULT_AUTHENTICATION_CLASSES":['app01.utils.auth.FirstAuthtication','app01.utils.auth.Authtication', ],
# "DEFAULT_AUTHENTICATION_CLASSES":['app01.utils.auth.FirstAuthtication', ],
# "UNAUTHENTICATED_USER":lambda :"匿名用户"
"UNAUTHENTICATED_USER":None, # 匿名,request.user = None
"UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None
"DEFAULT_PERMISSION_CLASSES":['app01.utils.permission.SVIPPermission',] # 权限类路径
}
-
2.4:如果不想全局使用,局部使用--只需要在对应的视图中加上permission_classes = [权限类,]即可
-
2.5:实现效果
-
3.权限源码流程
- 3.1:请求进来-->执行dispatch方法-->initialize_request方法封装request-->initial方法,认证/权限/频率等,check_permissions方法
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
# 权限对象列表
for permission in self.get_permissions():
if not permission.has_permission(request, self): # 如果没权限
self.permission_denied(
request,
message=getattr(permission, 'message', None),
code=getattr(permission, 'code', None)
)
- 3.2:执行get_permissions方法-->执行permission_classes,获取permission_classes对象,优先从视图自己,如果没有获取setting中的DEFAULT_PERMISSION_CLASSES字段
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
class APIView(View):
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
...
- 3.3:如果有权限对象(就循环执行自定义权限类的has_permission方法,如果返回True,有权限;如果返回False,没权限);如果没有,执行permission_denied抛出异常.
class BasePermission(metaclass=BasePermissionMetaclass):
"""
A base class from which all permission classes should inherit.
"""
def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
def has_object_permission(self, request, view, obj):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True