文章目录

  • 1、限流Throttling
    • 1.1、自定义频率类
      • 1.1.1、编写频率类
      • 1.1.2、全局使用
      • 1.1.3、局部使用
    • 1.2、内置频率类
      • 1.2.1、根据用户ip限制
      • 1.2.2、限制匿名用户每分钟访问3次
      • 1.2.3、限制登陆用户每分钟访问10次
      • 1.2.4、其他
        • 1.2.4.1、AnonRateThrottle
        • 1.2.4.2、UserRateThrottle
        • 1.2.4.3、ScopedRateThrottle
      • 1.2.5、全局配置中设置访问频率
      • 1.2.6、内置频率类使用总结
  • 2、内置过滤功能及第三方过滤功能
    • 2.1、内置过滤功能
    • 2.2、第三方扩展的过滤功能
    • 2.3、排序
  • 3、分页Pagination
    • 3.1、可选分页器
      • 3.1.1、PageNumberPagination
      • 3.1.2、LimitOffsetPagination
      • 3.1.3、CursorPagination
      • 3.1.4、应用
    • 3.2、三种分页的使用总结

1、限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力
一般用于付费购买次数,投票等场景使用

1.1、自定义频率类

1.1.1、编写频率类
# 自定义的逻辑
#(1)取出访问者ip
#(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
#(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
#(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
#(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
class MyThrottles():VISIT_RECORD = {}def __init__(self):self.history=Nonedef allow_request(self,request, view):#(1)取出访问者ip# print(request.META)ip=request.META.get('REMOTE_ADDR')import timectime=time.time()# (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问if ip not in self.VISIT_RECORD:self.VISIT_RECORD[ip]=[ctime,]return Trueself.history=self.VISIT_RECORD.get(ip)# (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,while self.history and ctime-self.history[-1]>60:self.history.pop()# (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过# (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败if len(self.history)<3:self.history.insert(0,ctime)return Trueelse:return Falsedef wait(self):import timectime=time.time()return 60-(ctime-self.history[-1])
1.1.2、全局使用
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES':['app01.utils.MyThrottles',],
}
1.1.3、局部使用
# 在视图类里使用
throttle_classes = [MyThrottles,]

1.2、内置频率类

1.2.1、根据用户ip限制
# 写一个类,继承自SimpleRateThrottle(根据ip限制)
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):scope = 'xxx'def get_cache_key(self, request, view):return self.get_ident(request)
#在setting里配置: (一分钟访问三次)
REST_FRAMEWORK = {'DEFAULT_THROTTLE_RATES':{'xxx':'3/m'  # key要跟类中的scop对应}
}
# 可以全局使用,局部使用

了解:错误信息中文显示

class Course(APIView):authentication_classes = [TokenAuth, ]permission_classes = [UserPermission, ]throttle_classes = [MyThrottles,]def get(self, request):return HttpResponse('get')def post(self, request):return HttpResponse('post')def throttled(self, request, wait):from rest_framework.exceptions import Throttledclass MyThrottled(Throttled):default_detail = 'xxx'extra_detail_singular = '还有 {wait} second.'extra_detail_plural = '出了 {wait} seconds.'raise MyThrottled(wait)
1.2.2、限制匿名用户每分钟访问3次
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.AnonRateThrottle',),'DEFAULT_THROTTLE_RATES': {'anon': '3/m',}
}
# 使用 `second`, `minute`, `hour` 或`day`来指明周期。
# 可以全局使用,局部使用
1.2.3、限制登陆用户每分钟访问10次
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'user': '10/m'}
}
# 可以全局使用,局部使用
1.2.4、其他
1.2.4.1、AnonRateThrottle
限制所有匿名未认证用户,使用IP区分用户
使用DEFAULT_THROTTLE_RATES['anon'] 来设置频次
1.2.4.2、UserRateThrottle
限制认证用户,使用User id 来区分
使用DEFAULT_THROTTLE_RATES['user'] 来设置频次
1.2.4.3、ScopedRateThrottle
限制用户对于每个视图的访问频次,使用ip或user idclass ContactListView(APIView):throttle_scope = 'contacts'...class ContactDetailView(APIView):throttle_scope = 'contacts'...class UploadView(APIView):throttle_scope = 'uploads'...
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ('rest_framework.throttling.ScopedRateThrottle',),'DEFAULT_THROTTLE_RATES': {'contacts': '1000/day','uploads': '20/day'}
}
1.2.5、全局配置中设置访问频率
'DEFAULT_THROTTLE_RATES': {'anon': '3/minute','user': '10/minute'
}
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottleclass StudentAPIView(RetrieveAPIView):queryset = Student.objects.all()serializer_class = StudentSerializerauthentication_classes = [SessionAuthentication]permission_classes = [IsAuthenticated]throttle_classes = (UserRateThrottle,)
1.2.6、内置频率类使用总结
1、使用局部使用throttle_classes = [auth.MyThrottle,]全局使用REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES':['app01.auth.MyThrottle',],}2、内置频率类BaseThrottle: 基类AnonRateThrottle: 限制匿名用户的访问次数SimpleRateThrottle: 咱么自定义扩写它ScopedRateThrottleUserRateThrottle: 限制登录用户访问次数3、扩展内置频率类定义一个类,继承SimpleRateThrottleclass MySimpleThrottle(SimpleRateThrottle):scope = 'xxx'def get_cache_key(self, request, view):# 以ip限制return self.get_ident(request)在setting.py中配置REST_FRAMEWORK = {'DEFAULT_THROTTLE_RATES' : {'xxx':'10/m'  # key跟scope对应,value是一个时间}}可以在局部使用和全局使用4、源码分析继承SimpleRateThrottle ---> allow_request5、其它内置频率类限制未登录用户的频率(AnonRateThrottle)(根据ip限制)使用:局部使用,全局使用setting.py中配置'DEFAULT_THROTTLE_RATES' : {'anon':'1/m'}限制登录用户访问次数UserRateThrottle(根据用户id限制)使用:局部使用,全局使用setting.py中配置'DEFAULT_THROTTLE_RATES' : {'user':'1/m'}

2、内置过滤功能及第三方过滤功能

2.1、内置过滤功能

过滤: 筛选查询结果
内置筛选的使用在视图类中配置:from rest_framework.filters import SearchFilterfilter_backends =[SearchFilter,]search_fields=('name',)  # 表模型中的字段查询的时候:http://127.0.0.1:8000/students/?search=e  # 支持模糊匹配

2.2、第三方扩展的过滤功能

# 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持
pip install django-filter  # 最新版本(2.4.0)要跟django2.2以上搭配
from django_filters.rest_framework import DjangoFilterBackend# 在配置文件中增加过滤后端的设置
INSTALLED_APPS = [...'django_filters',  # 需要注册应用
]
# 全局配置
REST_FRAMEWORK = {...'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}# 在视图中添加filter_fields属性,指定可以过滤的字段
class StudentListView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentSerializer# 类视图配置filter_backends = [DjangoFilterBackend, ]filter_fields = ['id', 'gender', 'name']查询的时候
# http://127.0.0.1:8000/stu/?gender=1

2.3、排序

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序使用方法:
在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明class StudentListView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializerfilter_backends = [OrderingFilter]ordering_fields = ('id', 'age')# 127.0.0.1:8000/books/?ordering=-age
# -id 表示针对id字段进行倒序排序
# id  表示针对id字段进行升序排序
如果需要在过滤以后再次进行排序,则需要两者结合from rest_framework.generics import ListAPIView
from students.models import Student
from .serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
class Student3ListView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializerfilter_fields = ('age', 'gender')# 因为局部配置会覆盖全局配置,所以需要重新把过滤组件核心类再次声明,# 否则过滤功能会失效filter_backends = [OrderingFilter,DjangoFilterBackend]ordering_fields = ('id', 'age')

3、分页Pagination

REST framework提供了分页的支持
我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 100  # 每页数目
}

可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明

class LargeResultsSetPagination(PageNumberPagination):page_size = 1000page_size_query_param = 'page_size'max_page_size = 10000class BookDetailView(RetrieveAPIView):queryset = BookInfo.objects.all()serializer_class = BookInfoSerializerpagination_class = LargeResultsSetPagination

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

3.1、可选分页器

3.1.1、PageNumberPagination

前端访问网址形式

GET  http://127.0.0.1:8000/students/?page=4

可以在子类中定义的属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为”page”
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量
# APIView
from rest_framework.pagination import PageNumberPagination
# 一 基本使用: url=url=http://127.0.0.1:8000/pager/?page=2&size=3,size无效
class  Pager(APIView):def get(self,request,*args,**kwargs):# 获取所有数据ret=models.Book.objects.all()# 创建分页对象page=PageNumberPagination()# 在数据库中获取分页的数据page_list=page.paginate_queryset(ret,request,view=self)# 对分页进行序列化ser=BookSerializer1(instance=page_list,many=True)return Response(ser.data)# 二 自定制: url=http://127.0.0.1:8000/pager/?page=2&size=3
# size=30,无效,最多5条
class Mypage(PageNumberPagination):page_size = 2page_query_param = 'page'# 定制传参page_size_query_param = 'size'# 最大一页的数据max_page_size = 5class  Pager(APIView):def get(self,request,*args,**kwargs):# 获取所有数据ret=models.Book.objects.all()# 创建分页对象page=Mypage()# 在数据库中获取分页的数据page_list=page.paginate_queryset(ret,request,view=self)# 对分页进行序列化ser=BookSerializer1(instance=page_list,many=True)# return Response(ser.data)# 这个也是返回Response对象,但是比基本的多了上一页,下一页,和总数据条数(了解即可)return page.get_paginated_response(ser.data)#ListAPIView
# 声明分页的配置类
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):# 默认每一页显示的数据量page_size = 2# 允许客户端通过get参数来控制每一页的数据量page_size_query_param = "size"max_page_size = 10# 自定义页码的参数名page_query_param = "p"class StudentAPIView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializerpagination_class = StandardPageNumberPagination# 127.0.0.1/four/students/?p=1&size=5
3.1.2、LimitOffsetPagination

前端访问网址形式

GET http://127.0.0.1/four/students/?limit=100&offset=400

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直
  • limit_query_param limit参数名,默认’limit’
  • offset_query_param offset参数名,默认’offset’
  • max_limit 最大limit限制,默认None
# APIView
# http://127.0.0.1:8000/pager/?offset=4&limit=3
from rest_framework.pagination import LimitOffsetPagination
# 也可以自定制,同简单分页
class  Pager(APIView):def get(self,request,*args,**kwargs):# 获取所有数据ret=models.Book.objects.all()# 创建分页对象page=LimitOffsetPagination()# 在数据库中获取分页的数据page_list=page.paginate_queryset(ret,request,view=self)# 对分页进行序列化ser=BookSerializer1(instance=page_list,many=True)# return page.get_paginated_response(ser.data)return Response(ser.data)#ListAPIView
from rest_framework.pagination import LimitOffsetPagination
class StandardLimitOffsetPagination(LimitOffsetPagination):# 默认每一页查询的数据量,类似上面的page_sizedefault_limit = 2limit_query_param = "size"offset_query_param = "start"class StudentAPIView(ListAPIView):queryset = Student.objects.all()serializer_class = StudentModelSerializer# 调用页码分页类# pagination_class = StandardPageNumberPagination# 调用查询偏移分页类pagination_class = StandardLimitOffsetPagination
3.1.3、CursorPagination

前端访问网址形式

GET http://127.0.0.1/four/students/?cursor=cD0xNQ%3D%3D

可以在子类中定义的属性:

  • cursor_query_param:默认查询字段,不需要修改
  • page_size:每页数目
  • ordering:按什么排序,需要指定
#APIView
from rest_framework.pagination import CursorPagination
# 看源码,是通过sql查询,大于id和小于id
class  Pager(APIView):def get(self,request,*args,**kwargs):# 获取所有数据ret=models.Book.objects.all()# 创建分页对象page=CursorPagination()page.ordering='nid'# 在数据库中获取分页的数据page_list=page.paginate_queryset(ret,request,view=self)# 对分页进行序列化ser=BookSerializer1(instance=page_list,many=True)# 可以避免页码被猜到return page.get_paginated_response(ser.data)# ListAPIView
class MyCursorPagination(CursorPagination):page_size=2ordering='-id'from rest_framework.generics import ListAPIView
class AuthorListView(ListAPIView):serializer_class = serializers.AuthorModelSerializerqueryset = models.Author.objects.filter(is_delete=False)pagination_class =MyCursorPagination
3.1.4、应用
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class MyPageNumberPagination(PageNumberPagination):page_size = 2page_query_param = 'page'# 定制传参page_size_query_param = 'size'# 最大一页的数据max_page_size = 5class MyLimitOffsetPagination(LimitOffsetPagination):default_limit = 2# 最大一页的数据max_limit = 5class MyCursorPagination(CursorPagination):page_size=2ordering='-id'from rest_framework.generics import ListAPIView
class AuthorListView(ListAPIView):serializer_class = serializers.AuthorModelSerializerqueryset = models.Author.objects.filter(is_delete=False)pagination_class =MyCursorPagination

3.2、三种分页的使用总结

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=55、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=16、CursorPagination: 游标分页(速度块)cursor_query_param = 'cursor'       # 查询的时候,指定的查询方式page_size = api_settings.PAGE_SIZE  # 每页显示多少条ordering = '-created'               # 排序方式page_size_query_param = size        # 查询的时候指定每页显示多少条max_page_size = None                # 每页最多显示多少条使用方式:定义一个类,继承CursorPagination重写四个属性在继承了GenericAPIView+ListModelMixin视图类中配置pagination_class = MyPageNumberPagination查询http://127.0.0.1:8000/students/?cursor=cD0xNQ%3D%3D               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) # 返回数据

Django rest framework之限流Throttling、内置过滤功能及第三方过滤功能及分页Pagination相关推荐

  1. Django Rest framework的限流实现流程

    目录 一 什么是throttle 二 Django REST framework是如何实现throttle的 三 Django REST framework中throttle源码流程 一 什么是thr ...

  2. python-DRF_限流Throttling_自定义频率类_内置频率类使用_过滤排序功能

    DRF-Django rest framework 认证权限频率 1. 限流Throttling 可以对接口访问的频次进行限制,以减轻服务器压力 一般用于付费购买次数,投票等场景使用 1. 自定义频率 ...

  3. Django 2.1.3 文档-模板-内置标签和过滤器(tagfilter)

    内置标签和过滤器 1.内置标签 一览 autoescape block comment csrf_token cycle debug extends filter(标签filter而不是过滤器filt ...

  4. RESTful之限流Throttling

    可以对接口访问的频次进行限制,以减轻服务器压力.[如防止爬虫软件] 使用 可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全 ...

  5. 限流Throttling

    可以对接口访问的频次进行限制,以减轻服务器压力. 使用 可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置, REST ...

  6. Nginx(OpenResty)+Lua+Redis IP限流 10s内

    使用 OpenResty 可以不用再次编译nginx 就能集成对应lua环境 可以扩展的模块比较丰富 1.使用redis 控制限流 ip 访问频度 创建对应lua脚本 access_by_limit_ ...

  7. kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 Kong 目前kong的最新版为2.2,官方git在https://github.com/Kong/kong,下面是一个kong的简单结构 kong的 ...

  8. Django实战(21):使用内置的Amin管理用户

    到目前为止,我们开发的所有功能都是匿名访问的,这显然不够安全.通常我们会要求注册的用户通过用户名和密码登录,只有登录后的用户才可以管理产品.套用专业的说法就是:第一步是认证,验证用户是否是他所宣称的那 ...

  9. 降压恒流芯片 内置MOS大功率共阳极LED恒流驱动IC

    ●工作原理 AP5170 采用峰值电流检测和固定关断时间的控制方式,电路工作在开关管导通和关断 两种状态. AP5170 典型应用图,当 MOS 开关管处于导通状态时.输入电压通过 LED 灯.电感. ...

最新文章

  1. android 8.0 l2tp问题,【Win】使用L2TP出現809錯誤
  2. 洛谷P2896 [USACO08FEB]一起吃饭Eating Together
  3. 工业控制软件测试评价体系,工业控制信息安全产品测试评价的体系.doc
  4. js处理json和字符串示例
  5. 实验2 递归下降语法分析程序设计
  6. JAVA Swing 组件演示***
  7. php 解析http,用PHP手动解析原始HTTP数据
  8. java get post 注解,GET/POST接收或发送数据的问题
  9. Mac下配置Android环境
  10. Mysql物化视图应用
  11. HDU2007 平方和与立方和【序列处理+入门】
  12. [转载] python--isalnum()函数
  13. 彻底解决“IIS配置401错误”
  14. 【OR】YALMIP 全局最优化
  15. 引入Google新技术 Picasa2发布
  16. 入门 | S3C2440启动过程分析
  17. ExtJS 更改penal标题栏样式
  18. 年薪50W+的Python程序员如何写代码
  19. 微信二维码海报推广示例
  20. 易基因项目文章 | 90天见刊,易基因m6A RNA甲基化(MeRIP)+转录组组学研究

热门文章

  1. 写一个PE的壳_Part 3:Section里实现PE装载器
  2. 【干货】如何有效地提问
  3. jsp中div 标签到底有什么用?
  4. 编程规范 --- 可读性
  5. pycharm连接云端服务器后实现远程debug调试
  6. 为什么要知己知彼?要有信息?
  7. 实用的 Python 自动化办公技巧
  8. python真的能赚钱吗,学python可以赚钱吗
  9. C++容器方法大汇总
  10. 数据库设计中的英文术语表