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={})
posted @ 2020-07-11 15:03  疏星淡月  阅读(252)  评论(0编辑  收藏  举报