【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
posted @ 2024-05-23 22:09  Tony_xiao  阅读(6)  评论(0编辑  收藏  举报