当你发现自己的才华撑不起野心时,就请安静下来学习吧。

Personal site

↑点击传送

权限、频率、过滤、排序、异常处理

权限、频率、过滤、排序、异常处理

权限

#源码分析
# 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)
                )
权限的完整使用
#写一个类,继承BasePermission,重写has_permission方法,里面写逻辑,如果权限通过返回True,否则False
    from rest_framework.permissions import BasePermission,重写
    class UserPermission(BasePermission):
        def has_permission(self, request, view):
            user = request.user
            if user.type == 1:
                return True
            else:
                return False
#全局配置
	REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ['app01.utils.permission.UserPermission'],
}
#局部禁用
	permission_class = []
#局部使用
	from app01.utils.permission import UserPermission
	permission_class = [UserPermission,]
内置权限的完整使用
#先登录admin页面,经过SessionAuthentication就会保存token然后经过IsAdminUser效验token,是判断is_staff字段1为True、0为False
#通过则可以访问TestAPIView了
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.permissions import IsAdminUser
    from rest_framework.authentication import SessionAuthentication

    class TestAPIView(APIView):
        authentication_classes = [SessionAuthentication,]
        permission_classes = [IsAdminUser,]
        def get(self,request,*args,**kwargs):
            return Response({"status":100,'msg':'成功'})

频率

内置频率限制(未登录用户)
#全局配置、限制未登录用户1分钟访问3次
	#views.py
        class TestAPIView(APIView):
        #需要搭配这两使用,局部禁用
        authentication_classes = []
        permission_classes = []
        def get(self,request,*args,**kwargs):
            return Response({"status":100,'msg':'成功'})
        #settings.py
            REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle',),
            'DEFAULT_THROTTLE_RATES': {'anon': '3/m',}
        }
#局部使用
	#views.py
		from rest_framework.throttling import AnonRateThrottle
        class Test2APIView(APIView):
            authentication_classes = []
            permission_classes = []
            throttle_classes = [AnonRateThrottle,]
            def get(self,request,*args,**kwargs):
                return Response({"status":100,'msg':'成功'})
    #settings.py需要配置频率  
    	    REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_RATES': {'anon': '3/m',}
        }
内置频率限制(登录用户跟未登录用户)
#全局配置,登录用户1分钟访问5次,未登录用户访问3次
	#views.py
		from rest_framework.throttling import AnonRateThrottle
        from rest_framework.throttling import UserRateThrottle
        from rest_framework.authentication import SessionAuthentication
        class Test2APIView(APIView):
            authentication_classes = [SessionAuthentication,]
            throttle_classes = [UserRateThrottle,AnonRateThrottle,]
            def get(self,request,*args,**kwargs):
                print(request.user)
                return Response({"status":100,'msg':'成功'})
	#settins.py
        REST_FRAMEWORK = {
            'DEFAULT_THROTTLE_CLASSES': (
                'rest_framework.throttling.AnonRateThrottle',
                'rest_framework.throttling.UserRateThrottle'),
            'DEFAULT_THROTTLE_RATES': {
                'user': '10/m',
                'anon': '5/m',}}
#局部配置
	#views.py
		from rest_framework.throttling import AnonRateThrottle
        from rest_framework.throttling import UserRateThrottle
        from rest_framework.authentication import SessionAuthentication
        class Test2APIView(APIView):
        	#搭配认证类、保存登录用户,不然登录了admin页面之后也是匿名用户
            authentication_classes = [SessionAuthentication,]
            throttle_classes = [UserRateThrottle,AnonRateThrottle,]
            def get(self,request,*args,**kwargs):
                print(request.user)
                return Response({"status":100,'msg':'成功'})
	#settings.py
        REST_FRAMEWORK = {
        'DEFAULT_THROTTLE_RATES': {
            'user': '10/m',
            'anon': '5/m',}}

过滤

1 安装pip3 install django-filter(最新版本需要django2.2以上)
2 在app中注册
	INSTALLED_APPS = [
    	'django_filters'
    	]
3 全局配
	#views.py
        from rest_framework.generics import ListAPIView
        class Test3APIView(ListAPIView):
            queryset = Book.objects.all()
            serializer_class = BookModelSerializer
             filter_fields = ('age', 'sex')#需要过滤的字段,可以加多个
    #settings.py
    	REST_FRAMEWORK = {
    		'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
    		}
4 局部配,导入的对象不一样,from rest_framework.filters import SearchFilter
	#局部过滤
        from rest_framework.generics import ListAPIView
        from rest_framework.filters import SearchFilter
        class Test4APIView(ListAPIView):
            queryset = Book.objects.all()
            serializer_class = BookModelSerializer
            filter_backends = [SearchFilter]
            search_fields = ['name', 'price']

排序

#局部配置
	from rest_framework.generics import ListAPIView
    from rest_framework.filters import OrderingFilter
    from app01.models import Book
    from app01.ser import BookSerializer
    class BookListAPIView(ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        filter_backends = [OrderingFilter,]
        ordering_fields = ('id', 'price')
	#使用
        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

自定义异常处理

#全局配置
	#views.py
	from rest_framework.views import exception_handler
    from rest_framework.response import Response
    from rest_framework import status
    def my_exception_handler(exc,context):
        response = exception_handler(exc,context)
        if not response:
            if isinstance(exc,ZeroDivisionError):
                return Response(data={'status':444,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)
            return Response(data={'status':999,'msg':str(exc)},status=status.HTTP_400_BAD_REQUEST)

        else:
            Response(data={'status':888,'msg':response.data.get('detail')},status=status.HTTP_400_BAD_REQUEST)
	#settings.py
		REST_FRAMEWORK = {
            'EXCEPTION_HANDLER': 'app01.app_auth.my_exception_handler',}
 #局部使用
 在需要的地方
 from rest_framework import status
 return Response(data={"name": "PrivateIdNotUniqueException", "message": "", "data": None,
                                  "autoAlert": False}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

封装Response对象(重要)

#以后都用自己封装的
	from rest_framework.response import Response
    class APIResponse(Response):
        def __init__(self, code=100,msg='成功',data=None,status=None,headerrs=None,**kwargs):
            dic = {'code':code,msg:msg}
            if data:
                dic = dic['data'] = data
            dic.update(kwargs)
            super().__init__(data=dic,status=status,headers=headerrs)
    #使用       
    	return APIResponse(data={"name":'lqz'},token='dsafsdfa',aa='dsafdsafasfdee')

数字后加逗号是元祖

a=(3,)	a=3, 这两是一样的
print(type(a))#<class 'tuple'>
posted @ 2020-07-21 16:25  Joab-0429  阅读(158)  评论(0编辑  收藏  举报