django-restframework分页器、全局异常及自封装response对象等相关内容-88

1 编写登录接口,图书5大接口,实现图书5大接口匿名用户一分钟访问3次,登录用户一分钟访问10次

	-方式一:
    	-写两个频率类(一个是根据ip限制,另一个根据userid)
    -方式二:
    	-使用内置的,如果可以,就没问题就可以,如果又问题需要继承重写get_cache_key方法
2 一个接口既可以不登录访问,又可以登录访问(匿名用户一分钟访问3次,登录用户一分钟访问10次)
	-认证类:额外写
    	class LoginAuth(BaseAuthentication):
            def authenticate(self, request):
                token = request.GET.get('token')
                res = models.UserToken.objects.filter(token=token).first()
                if res:
                    return (res.user, token)
                else:
                    return None
    -登录用户的频率限制
        class MySimpleThrottle(SimpleRateThrottle):
            scope = 'xxx'
            def get_cache_key(self, request, view):
                if not request.user.id:# 没有登录用户
                    return self.get_ident(request) #根据ip限制
                else:
                    return None
    -未登录用户的频率限制
        class MyLoginThrottle(SimpleRateThrottle):
            scope = 'login'
            def get_cache_key(self, request, view):
                return request.user.pk    
            
 -排序(内置排序规则)
	-在视图类中配置
    	filter_backends =[OrderingFilter,]
		ordering_fields=['id','age']
    -查询:
    	http://127.0.0.1:8000/students/?ordering=-age
 -过滤(内置)
	-在视图类中配置
    	filter_backends =[SearchFilter,]
		search_fields=('name','age')
    -查询:
    	http://127.0.0.1:8000/students/?search=9,l
                
 -过滤(django-filter)
	-在视图类中配置
    	filter_backends =[DjangoFilterBackend,]
		filter_fields=['name','age']
    -查询:
    	http://127.0.0.1:8000/students/?name=lqz&age=10
                
-自定制过滤器
	-查询所有才会有过滤---》list才需要过滤---》queryset = self.filter_queryset(self.get_queryset())---》GenericAPIView-->filter_queryset
    
    
        def filter_queryset(self, queryset):
            for backend in list(self.filter_backends):
                queryset = backend().filter_queryset(self.request, queryset, self)
            return queryset
        

	

0 自定制过滤器

基于django-filter扩写

1 写一个类MyFilter,继承BaseFilterBackend
2 重写filter_queryset方法,在该方法内部进行过滤(自己设置的过滤条件)
3 返回queryset对象(过滤后的queryset对象)
4 配置在视图类中
	filter_backends = [MyFilter,]

1 分页器(三种)重点如何使用

1 内置了三种分页器
	-PageNumberPagination:普通分页
    -LimitOffsetPagination:偏移分页
    -CursorPagination:游标分页
2 APIView和GenericAPIView+ListModelMixin

3 GenericAPIView+ListModelMixin的分页模式
	
4 PageNumberPagination:普通分页(用的最多)
	-page_size = api_settings.PAGE_SIZE  # 每页显示多少条
    -page_query_param = 'page'           # 查询参数
    -page_size_query_param = size        # 查询的时候指定每页显示多少条
    -max_page_size = 10                # 每页最多显示多少条
    
    -使用方式:
    	-定义一个类,继承PageNumberPagination
        -重写四个属性
        -在继承了GenericAPIView+ListModelMixin视图类中配置
        	pagination_class = MyPageNumberPagination
        -查询
        	http://127.0.0.1:8000/students/?page=1&size=5
            
5 LimitOffsetPagination:偏移分页
    -default_limit = api_settings.PAGE_SIZE  # 默认条数
    -limit_query_param = 'limit'             # 查询时,指定查询多少条
    -offset_query_param = 'offset'           # 查询时,指定的起始位置是哪 
    -max_limit = None                        # 查询时,最多返回多少条
    -使用方式:
    	-定义一个类,继承LimitOffsetPagination
        -重写四个属性
        -在继承了GenericAPIView+ListModelMixin视图类中配置
        	pagination_class = MyPageNumberPagination
        -查询
        http://127.0.0.1:8000/students/?limit=100&offset=1
6 CursorPagination:游标分页(速度块)
	-cursor_query_param = 'cursor'  # 查询的时候,指定的查询方式
    -page_size = api_settings.PAGE_SIZE # 每页显示多少条
    -ordering = '-created'   # 排序方式
    -page_size_query_param = size  # 查询的时候指定每页显示多少条
    -max_page_size = None          #每页最多显示多少条
    -使用方式:
            -定义一个类,继承LimitOffsetPagination
            -重写四个属性
            -在继承了GenericAPIView+ListModelMixin视图类中配置
                pagination_class = MyPageNumberPagination
            -查询
            http://127.0.0.1:8000/students/?limit=100&offset=1
                    
                    
 7 APIView的分页模式
	-新建一个类,继承普通分页,重写四个属性
    -视图类写法如下
	class StudentApiView(APIView):
        def get(self,request):
            student_list=Student.objects.all()
            page=MyPageNumberPagination()# 实例化得到对象
            # 只需要换不同的分页类即可
            res=page.paginate_queryset(student_list,request,self)# 开始分页
            ser=StudentSerializer(res,many=True)
            return page.get_paginated_response(ser.data) # 返回数据

2 全局异常

1 统一接口的返回方式,即便视图函数执行出错
2 使用方式
	-写一个函数
    def common_exception_handler(exc, context):
        response = exception_handler(exc, context)
        if response is None:
            response = Response({'code':999,'detail': '未知错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        return response
   	-在setting中配置
    	REST_FRAMEWORK = {
    		'EXCEPTION_HANDLER':'app01.utils.common_exception_handler'
		}

3 封装Response对象

1 以后都使用自己封装的response
class APIResponse(Response):
    def __init__(self, code=100, msg='成功', data=None, status=None, headers=None, content_type=None, **kwargs):
        dic = {'code': code, 'msg': msg}
        if data:
            dic['data'] = data

        dic.update(kwargs) # 这里使用update
        super().__init__(data=dic, status=status,
                         template_name=None, headers=headers,
                         exception=False, content_type=content_type)
2 使用:
	return APIResponse(code=100,msg='查询成功',data=ser.data,count=200,next='http://wwwa.asdfas')

4 自动生成接口文档

1 借助于第三方:coreapi,swagger
2 在路由中
    from rest_framework.documentation import include_docs_urls
    path('docs/', include_docs_urls(title='图书管理系统api'))
3 在配置文件中
	REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
	}
4 写视图类(需要加注释)
    class BookListCreateView(ListCreateAPIView):
        """
        get:
        返回所有图书信息.
        asdfasfda

        post:
        新建图书.
        """
        queryset = Student.objects.all()
        serializer_class = StudentSerializer
5 只需要在浏览器输入,就可以看到自动生成的接口文档()
	http://127.0.0.1:8000/docs/
posted @ 2021-01-19 19:08  投降输一半!  阅读(187)  评论(0编辑  收藏  举报