• DRF权限频率过滤异常处理


    DRF权限频率过滤异常处理

    1 权限

    1.1 权限源码的分析

    # APIView---->dispatch---->initial--->self.check_permissions(request)(APIView的对象方法)
        def check_permissions(self, request):
            # 遍历权限对象列表得到一个个权限对象(权限器),进行权限认证
            for permission in self.get_permissions():
                # 权限类一定有一个has_permission权限方法,用来做权限认证的
                # 参数:权限对象self、请求对象request、视图类对象
                # 返回值:有权限返回True,无权限返回False
                if not permission.has_permission(request, self):
                    self.permission_denied(
                        request, message=getattr(permission, 'message', None)
                    )
    

    1.2 自定义权限

    from rest_framework.permissions import BasePermission
    
    
    # 自定义权限
    class UserPermission(BasePermission):
        def has_permission(self, request, view):
            if request.user.types == 0:   # 0为超级用户,直接返回True
                return True
            elif request.user.types == 1: # 1为会员用户,只具有'GET'和'POST'的权限
                return request.method in ['GET', 'POST']
            elif request.user.types == 2: # 2为普通用户,只具有‘GET’权限
                return request.method == 'GET'
            else:
                return False
    

    局部使用:

    from app01.utils.auth_check import LogAuthentication
    class LoginView(APIView):
        # 自定义方法
        authentication_classes = []
        permission_classes = [LogAuthentication,]
    
        def post(self, request):
            username = request.data.get('username')
            password = request.data.get('password')
            user = User.objects.filter(username=username, password=password).first()
            if user:
                token = ''.join(str(uuid4()).split('-')).upper()
                token_obj = APIToken.objects.update_or_create(defaults={'token': token}, user=user)
                return APIResponse(data={'token': token})
            else:
                return APIResponse(code='103', msg='用户不存在')
    

    全局使用

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [  # 权限的全局配置
            # 'app01.utils.permission.UserPermission', # 自定义的权限配置
            'rest_framework.permissions.IsAdminUser',  # 使用内置的权限配置
        ],
    }
    

    局部禁用

    class LoginView(APIView):
        # 自定义方法
        authentication_classes = []
        permission_classes = []
    

    1.3 内置权限的使用(了解)

    class Login2View(APIView):
        # 内置的方法
        authentication_classes = []
        permission_classes = []
    
        def post(self, request):
            username = request.data.get('username')
            password = request.data.get('password')
            user = auth.authenticate(username=username, password=password)
            if user:
                auth.login(request, user)
                return APIResponse(msg='登录成功', data={'user': request.user.username})
            else:
                return APIResponse(code='103', msg='用户不存在')
    

    2 过滤&排序

    2.1 过滤

    安装第三方模块django-filter,注意django的版本需要在 2.2以及之上

    pip install django-filter
    

    查看django的版本

    >>> import django
    >>> print(django.VERSION)
    (2, 2, 14, 'final', 0)
    

    局部使用

    from django-filter.rest_framework import DjangoFilterBackend
    
    from rest_framework.generics import ListAPIView
    class Book3View(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = GETSerializer
        filter_backends = (DjangoFilterBackend,OrderingFilter)
        filter_fields = ['name'] # 参与过滤的字段
        ordering_fields = ('id','price') # 参与排序的字段
    

    全局使用

    # 在app中进行注册
    INSTALLED_APPS = [
        'rest_framework',
        'django-filter', #针对浏览器
    ]
    
    # REST_FRAMEWORK = {
    	'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    }
    
    # Views.py
    class BookView(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        filter_fields = ('name',)  #配置可以按照哪个字段来过滤
    

    2.2 排序

    # 局部使用
    from rest_framework.filters import OrderingFilter
    from django_filters.rest_framework import DjangoFilterBackend
    
    from rest_framework.generics import ListAPIView
    class Book3View(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = GETSerializer
        filter_backends = (DjangoFilterBackend,OrderingFilter)
        filter_fields = ['name'] # 参与过滤的字段
        ordering_fields = ('id','price') # 参与排序的字段
        
    # 全局配置
    REST_FRAMEWORK = {
    	'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend','rest_framework.filters.OrderingFilter',)
    }
    
    

    3 频率

    3.1 内置频率的限制(限制未登录的用户)

    # 全局使用  限制未登录用户1分钟访问5次
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '3/m',
        }
    }
    ##############views.py
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication,BasicAuthentication
    class TestView4(APIView):
        authentication_classes=[]
        permission_classes = []
        def get(self,request,*args,**kwargs):
            return Response('我是未登录用户')
    
    # 局部使用
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication,BasicAuthentication
    from rest_framework.throttling import AnonRateThrottle
    class TestView5(APIView):
        authentication_classes=[]
        permission_classes = []
        throttle_classes = [AnonRateThrottle]
        def get(self,request,*args,**kwargs):
            return Response('我是未登录用户,TestView5')
    

    3.2 内置频率(限制用户访问的次数)

    # 需求:未登录用户1分钟访问5次,登录用户一分钟访问10次
    全局:在setting中
      'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
            'rest_framework.throttling.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'user': '10/m',
            'anon': '5/m',
        }
            
     局部配置:
    	在视图类中配一个就行
    

    4 异常处理

    from rest_framework.views import exception_handler
    from rest_framework.response import Response
    from rest_framework import status
    
    
    def api_exception_handler(exc, context):
        response = exception_handler(exc, context)
        # 一种是None,drf没有处理
        # 另外一种是Response对象(Django处理的),但是不符合我们的要求
        # print(type(exc))
    
        if not response:
            if isinstance(exc, ZeroDivisionError):
                return Response(data={'status': 777, 'msg': "除以0的错误" + str(exc)}, status=status.HTTP_400_BAD_REQUEST)
            return Response(data={'status': 999, 'msg': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
        else:
            # return response
            return Response(data={'status': 888, 'msg': response.data.get('detail')}, status=status.HTTP_400_BAD_REQUEST)
    

    5 封装Response

    # 以后都用自己封装的
    class APIResponse(Response):
        def __init__(self,code=100,msg='成功',data=None,status=None,headers=None,**kwargs):
            dic = {'code': code, 'msg': msg}
            if  data:
                dic = {'code': code, 'msg': msg,'data':data}
            dic.update(kwargs)
            super().__init__(data=dic, status=status,headers=headers)
    # 使用
    return APIResponse(data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee')
    return APIResponse(data={"name":'lqz'})
    return APIResponse(code='101',msg='错误',data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee',header={})
    
  • 相关阅读:
    TWaver3D直线、曲线、曲面的绘制
    react开发教程(六)React与DOM
    java Web开发实现手机拍照上传到服务器
    手把手教你从零写一个简单的 VUE--模板篇
    file_get_contents函数获取不到数据的一种情况
    Windows系统下批处理快速创建WIFI
    操作系统题库之简答题部分(个人整理,附带答案)
    回溯到底是个什么东西(含有大量经典例题加详细分析)
    到底什么是dp思想(内含大量经典例题,附带详细解析)
    一次性弄懂到底什么叫做分治思想(含有大量经典例题,附带详细解析)
  • 原文地址:https://www.cnblogs.com/surpass123/p/13285451.html
Copyright © 2020-2023  润新知