zoukankan      html  css  js  c++  java
  • drf权限、封装、过滤、排序、异常处理、Rsponse封装

    1、权限

    1.1、权限源码解析

    ​ 源码位置:APIView=》dispatch=》initial===》self.check_permissions(request) (APIView的对象方法)

    ​ 可以通过源码看出先是遍历权限对象列表得到一个个权限对象(也就是权限器),新型权限认证

    ​ 权限类有一个has_permission的权限认证方法,用来判断是否有权限

    ​ 涉及到的参数:权限对象self,请求对象request,以及视图类对象

    ​ 返回值:有权限就返回True,无权限返回False

        def check_permissions(self, request):
            for permission in self.get_permissions():
                if not permission.h
                (request, self):
                    self.permission_denied(
                        request, message=getattr(permission, 'message', None)
    

    1.2、权限的使用

    ​ 先在app_auth写一个类,用来继承Basepermission,重写has_permission,根据前端传送过来的数据的user_type进行对比,如果权限通过,就返回True,无权限就返回False

    from rest_Permission(BasePermission):
    class Userpermission(BasePermission)
    	def has_permission(self,request,view):
    		user = request.user
    		print(user.get_user_type_disproy())     #可以获取用户choice后面的中文
            if user.user_type == 1:
            	return True
            else:
            	return False
    		
    

    1.3、全局使用和局部使用

    局部使用:
    class Test(APIView):
    	permission_classes = [app_auth.UserPermission]
    全局使用:
    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",],
        'DEFAULT_PERMISSION_CLASSES': [
            'app01.app_auth.UserPermission',
        ],
    }
    局部禁用:
    class TestView(APIView):
        permission_classes = []
    
    

    1.4、内置权限(了解)

    # 演示一下内置权限的使用:IsAdminUser,控制是否对网站后台有权限的人
    # 1 创建超级管理员
    # 2 写一个测试视图类
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication
    class TestView3(APIView):
        authentication_classes=[SessionAuthentication,]
        permission_classes = [IsAdminUser]
        def get(self,request,*args,**kwargs):
            return Response('这是22222222测试数据,超级管理员可以看')
    # 3 超级用户登录到admin,再访问test3就有权限
    # 4 正常的话,普通管理员,没有权限看(判断的是is_staff字段)
    

    2、频率

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

    ​ 频率功能是内置的,直接使用就行,主要分为全局使用和局部使用

    ​ 1.全局使用

    1.在setting中设置
    REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '3/m',
        }
    }
    2.由于是未登录用户,所以需要将views.py中认证功能和权限功能都关闭
    from rest_framework.permissions import IsAdminuser
    from rest_framework.Authentication import SessionAuthentication
    class Testview(APIView):
    	authentication_classes = []    #关闭认证功能
    	permission_class = []		#关闭权限功能
    	def get(self,request,*args,**kwargs):
    		retrun Response('我是未登录用户')
    

    ​ 2.局部使用

    ​ 在需要使用的类中加入AnonRateThrottle 模块

    from rest_framework.throttling import AnonRateThrottle
    class Testview(APIView):
    	throttle_classes = [AnonRateThrottle]
    

    2.2、内置频率限制登录用户访问频率

    ​ 需求:将未登录用户1分钟访问5次,登录用户1分钟访问10次

    ​ 全局:在setting中:

      'DEFAULT_THROTTLE_CLASSES': (
      		‘rest_framework.throttling.AnnoRateThrottle’,
            'rest_framework.throtting.UserRateThrottle'
        ),
        'DEFAULT_THROTTLE_RATES': {
            'user': '10/m',
            'anon': '5/m',
        }
    

    ​ 局部:

    ​ 在需要使用并且已经登录认证的类中加入AnonRateThrottle 模块

    from rest_framework.throttling import AnonRateThrottle
    class Testview(APIView):
    	throttle_classes = [AnonRateThrottle]
    

    3、过滤

    ​ 过滤功能是可以单独使用的,单独建立一个路径,填写数据对数据库进行查找

    ​ 需要安装:pip3 install django-filter

    ​ 注册:在setting中添加:'django-filter'

    ​ 配置:在全局或者局部进行配置

    'DEFAULT_FILTER_BACKENDS':('django_filter.rest_framework.DjangoFilterBakend')
    
    

    ​ 视图类中:

    ​ 添加字段,可以按照那个字段进行筛选

    from rest_framework.generics import ListAPIView
    from app01.models import Book
    from app01.ser import BookSerializer
    class BookView(ListAPIview)
    	queryset = Book.objects.all()
        serializer_class = BookSerializer
        filter_fields = ('name','age',)
    

    4、排序

    ​ 排序需要导入OrderingFilter模块,可以和过滤一起使用

    ​ 在全局中的设置和过滤功能是一致的,排序可以单独使用也可以和过滤一起使用。区别在于过滤使用的是filter_fields属性而排序使用的是ordering_fields属性,当二者合一的时候使用的是ordering属性,并且需要在filter_backends属性里面放置Djangofilterbackend,表示,先排序后过滤

    from rest_framework.generics import ListAPIView
    from rest_framework.filters import OrderingFilter
    from app01.models import Book
    from app01.ser import Bookserializer
    class Bookview(ListAPIView):
    	queryset = Book.objects.all()
    	serializer_class = Bookserializer
    	filter_backends = [OrderingFiter]
    	ordering_fields = ('id','price')
    	
    排序和过滤结合使用,需要更改为:
    	filter_backends = [orderingFilter,Djangofilterbackend]
    
    urls.py
    url('book/',views.Bookview.as_view())
    
    路径的使用:
    http://127.0.0.1:8000/books2/?ordering=-price     #倒序
    http://127.0.0.1:8000/books2/?ordering=price
    http://127.0.0.1:8000/books2/?ordering=-id
    

    5、异常处理

    异常处理是通过统一接口的返回,自己编写一个方法,自定义异常处理

    异常分两种情况:第一种是none,drf没有处理,使用response捕捉,无响应

    ​ 第二种是response对象,django处理了,但是不符合我们的要求,使用isinstance处理,数据库数据异常

    fom rest_framework.views import exception_handlr
    def my_exception_hendler(exc,context):
    	response = exception_handler(exc,context)
    	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(data={'status':888,'msg':response.data.get('detail')},status=status.HTTP_400_BAD_REQUEST)
    		
    全局设置setting
    'EXCEPTION_HANDLER': 'app01.app_auth.my_exception_handler',
    

    6、封装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,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={})
    
  • 相关阅读:
    regsvr32.exe使用详解
    Windows默认文件操作(SHFileOperation)
    远程唤醒
    delphi事务
    rar行命令
    命令前加./ ,在后台运行程序 linux批处理 linux自动运行程序
    javascript基础知识(1)
    (三) MySQL事务与锁机制
    代码风格 java
    一切之始 java
  • 原文地址:https://www.cnblogs.com/jingpeng/p/13283613.html
Copyright © 2011-2022 走看看