权限,频率,过滤,异常处理

权限

权限源码分析

  1. 我们还是从入口点开始
APIView--> dispatch--> initial--> check_permissions

check_permissions源码

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

权限的使用

在写一个类,继承BasePermission,重写has_permission,如果权限通过,就返回True,不通过就返回False

class UserPermision(BasePermission):
    def has_permission(self, request, view):
        # 不是超级用户就不能访问
        # 认证通过,request内就有了user对象,当前的登录用户,取出当前用户
        user = request.user
        print(user.get_user_type_display())
        if user.user_type == 1:
            return True
        return False

测试数据

# 局部使用超级用户使用
class TestView(APIView):
    permission_classes = [UserPermision]

    def get(self,request):
        return Response("这是测试数据")
# 全局使用
class TestView1(APIView):
    def get(self,request):
        return Response("这是测试数据")
全局使用要在settings里面配置一下
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.authssssssssssss.MyAuthentication", ],
    'DEFAULT_PERMISSION_CLASSES': [
        'app01.authssssssssssss.UserPermision',
    ],
}


# 局部禁用
class TestView2(APIView):
    permission_classes = []
    def get(self,request):
        return Response("这是测试数据")

内置权限

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("这是测试数据")

频率

内置的频率限制

使用限制未登录

# 全局使用  限制未登录用户1分钟访问3次
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')

使用限制登录用户

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

过滤

#1 安装:pip3 install django-filter
#2 注册,在app中注册
#3 全局配,或者局部配
 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
#4 视图类
class BookView(ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_fields = ('name',)  #配置可以按照哪个字段来过滤

排序


from rest_framework.filters import OrderingFilter
class BooK1View(ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ('id',"name")
# 使用:

http://127.0.0.1:8000/books2/?ordering=name
http://127.0.0.1:8000/books2/?ordering=-id

异常处理

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)
    # 两种情况,一个是None,drf没有处理
    #response对象,django处理了,但是处理的不符合咱们的要求
    # print(type(exc))
    print(type(exc))# 这里可以打印出更详细的错误信息
    if isinstance(exc,ZeroDivisionError):
        return Response(data={'status':777,'msg':"o的错误"},status=status.HTTP_400_BAD_REQUEST)

    if not response:

        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)



封装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={})
posted @ 2020-07-11 18:34  小子,你摊上事了  阅读(107)  评论(0编辑  收藏  举报