DRF Django REST framework 之 频率,响应器与分页器组件(六)

频率组件

频率组件类似于权限组件,它判断是否给予请求通过。频率指示临时状态,并用于控制客户端可以向API发出的请求的速率。

与权限一样,可以使用多个调节器。API可能会对未经身份验证的请求进行限制,而对于经过身份验证的请求则进行限制较少。

例如,可以将用户限制为每分钟最多60个请求,每天最多1000个请求。

自定义频率组件

使用方式与权限,认证组件几乎相同

该方式没有DRF提供的方式简洁

import time
import math

from rest_framework import exceptions

class MyException(exceptions.Throttled):
    default_detail = ‘连接次数过多‘
    extra_detail_plural = extra_detail_singular = ‘请在{wait}秒内访问‘

    def __init__(self, wait=None, detail=None, code=None):
        super().__init__(wait=wait, detail=detail, code=code)

class VisitThrottle():
    user_visit_information = dict()
    visited_times = 1
    period = 60
    allow_times_per_minute = 5
    first_time_visit = True

    def allow_request(self, request, view):
        self.request_host = request_host = request.META.get("REMOTE_ADDR")
        current_user_info = self.user_visit_information.get(request_host, None)

        if not self.__class__.first_time_visit:
            self.user_visit_information[request_host][0] += 1
            current_visit_times = self.user_visit_information[request_host][0]

            if current_visit_times > self.allow_times_per_minute:
                if self._current_time - current_user_info[1] <= self.period:
                    if len(current_user_info) > 2:
                        current_user_info[2] = self._time_left
                    else:
                        current_user_info.append(self._time_left)

                    view.throttled = self.throttled
                    return None
                else:
                    self.__class__.first_time_visit = True

        if self.first_time_visit:
            self.__class__.first_time_visit = False
            self._initial_infomation()

        return True

    def wait(self):
        return self.period - self.user_visit_information[self.request_host][2]

    def throttled(self, request, wait):
        raise MyException(wait=wait)

    @property
    def _current_time(self):
        return time.time()

    @property
    def _time_left(self):
        return math.floor(self._current_time - self.user_visit_information.get(self.request_host)[1])

    def _initial_infomation(self):
        self.user_visit_information[self.request_host] = [self.visited_times, self._current_time]

基于每个视图设置频率:

class BookView(ModelViewSet):# 指定频率类,固定写法
    throttle_classes = [RateThrottle]
    # 获取数据源, 固定写法
    queryset = models.Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

使用DRF简单频率控制(局部)

from rest_framework.throttling import SimpleRateThrottle

class RateThrottle(SimpleRateThrottle):
    # 每分钟最多五次
    rate = ‘5/m‘

    def get_cache_key(self, request, view):
        return self.get_ident(request)

rate代表访问评率,上面表示每分钟五次, get_cache_key 是必须存在的,它的返回值告诉当前频率控制组件要使用什么方式区分访问者(比如ip地址)。

在视图中使用:

class BookView(ModelViewSet):
    # 指定频率类,固定写法
    throttle_classes = [RateThrottle]
    # 获取数据源, 固定写法
    queryset = models.Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

全局频率控制

首先定义一个频率控制类,并且必须继承 SimpleRateThrottle 这个类,它是DRF提供的一个方便的频率控制类,请看下面的代码:

from rest_framework.throttling import SimpleRateThrottle

class RateThrottle(SimpleRateThrottle):
    scope = "visit_rate"

    def get_cache_key(self, request, view):
        return self.get_ident(request)

在全局配置频率控制参数:

REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES": (‘app.utils.throttles.RateThrottle‘,),
    "DEFAULT_THROTTLE_RATES": {
        "visit_rate": "5/m"
    }
}

这样就实现了,每分钟最多五次访问的逻辑。

另外,可以使用 DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES 设置全局设置默认的限制策略。

例如:

REST_FRAMEWORK = {
    ‘DEFAULT_THROTTLE_CLASSES‘: [
        ‘rest_framework.throttling.AnonRateThrottle‘,
        ‘rest_framework.throttling.UserRateThrottle‘
    ],
    ‘DEFAULT_THROTTLE_RATES‘: {
        # 游客每天访问次数不能超过100次
        ‘anon‘: ‘100/day‘,
        # 用户每天访问次数不能超过1000次
        ‘user‘: ‘1000/day‘
    }
}

响应器

在使用DRF的Response类来将数据响应给客户端时,不管是POSTMAN工具还是浏览器,都能浏览到经过格式化后的,清晰易懂数据,DRF是怎么做的呢?其实就是通过响应器组件

响应器组件的使用

如果不需要使用DRF提供给浏览器的格式化后的数据,只需要禁止该响应方式即可:

from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer

class BookView(ModelViewSet):
    # 指定响应器类,固定写法,返回json格式数据
    renderer_classes = [JSONRenderer]
    # 获取数据源, 固定写法
    queryset = models.Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

这样,浏览器再次访问,接收到的就是普通的json格式数据,而不是经过DRF格式化后的数据,renderer_classes的查找逻辑与之前的解析器等等组件是完全一样的。

分页器

为了服务器性能考虑,也为了用户体验,我们不应该一次将所有的数据从数据库中查询出来,返回给客户端浏览器,如果数据量非常大,这对于服务器来讲,可以说是性能灾难,而对于用户来讲,加载速度将会非常慢。

而分页器能很好的解决该问题。

分页器的使用

第一步:导入模块

from rest_framework.pagination import PageNumberPagination

第二步:获取数据

books = Book.objects.all()

第三步:创建分页器

paginater = PageNumberPagination()

第四步:开始分页

paged_books = paginater.paginate_queryset(books, request)

第五步:将分页后的数据进行序列化

serialized_data = BookSerializer(paged_books, many=True)

第六步:返回数据

return Response(serialized_data.data)

常用参数介绍

常用分页器参数:
1. page_size:        用来控制每页显示多少条数据(全局参数名为PAGE_SIZE);
2. page_query_param:    用来提供直接访问某页的数据;
3. page_size_query_param: 临时调整当前显示多少条数据
4. max_page_size:       控制page_size_query_param参数能调整的最大条数

偏移分页器参数
1. default_limit:      每页显示的数据条数
2. offset_query_param:   要偏移的标杆,在前端以get的形式传,key为offset(‘可修改‘)
3. limit_query_param:   偏移量,在前端以get的形式传,key为limit(‘可修改‘)
4. max_limit:         一页最大的显示条数

自定义分页器

常用分页器 url :

# url:示例
http://http://127.0.0.1:8000/books/?page=2
# 在第二页显示,100条,但是page_size最大不能超过定义的max_page_size
http://http://127.0.0.1:8000/books/?page=2&page_size=100

常用分页器类:

from rest_framework.pagination import PageNumberPagination

# 定义分页器类
class BookPageNumberPagination(PageNumberPagination):
    # 默认一页条数
    page_size = 2
    # 前端发送的页数关键字名
    page_query_param = ‘page‘
    # 用户自定义一页条数 关键字名
    page_size_query_param = ‘page_size‘
    # 用户自定义一页最大控制条数
    max_page_size = 2

偏移分页器 url :

# url:示例
http://http://127.0.0.1:8000/books/?limit=10
# 在100条后显示10条, 但是显示的条数不能超过定义的max_limit
http://http://127.0.0.1:8000/books/?limit=10&offset=100

偏移分页器类:

from rest_framework.pagination import LimitOffsetPagination

class BookLimitOffsetPagination(LimitOffsetPagination):
    # 默认一页条数
    default_limit = 2
    # 从offset开始往后显示limit条
    limit_query_param = ‘limit‘
    offset_query_param = ‘offset‘
    # 最大显示多少条
    max_limit = 4

视图类使用:

class BookView(ModelViewSet):
    # 指定分页器类,固定写法,只能指定一个分页器类
    pagination_class = BookPageNumberPagination
    # pagination_class = BookLimitOffsetPagination
    # 获取数据源, 固定写法
    queryset = models.Book.objects.all()
    # 序列化类, 固定写法
    serializer_class = BookSerializer

~>.<~

原文地址:https://www.cnblogs.com/pungchur/p/12043539.html

时间: 2024-08-30 03:57:17

DRF Django REST framework 之 频率,响应器与分页器组件(六)的相关文章

轻轻松松学会 DRF Django REST framework

DRF Django REST framework 之 APIView(一) DRF Django REST framework 之 解析器(二) DRF Django REST framework 之 序列化(三) DRF Django REST framework 之 视图组件(四) 持续更新中.... 原文地址:https://www.cnblogs.com/pungchur/p/12028316.html

Django REST Framework之频率限制

开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用 使用 自定义频率限制组件:utils/thottle.py class MyThrottle(BaseThrottle): def __init__(self): self.history = None def allow_request(self, request, view): # 实现限流的逻辑 # 以IP限流 # 访问列表 {IP: [time1, time2, time3]} # 1, 获取请求的IP地址 i

DRF (Django REST framework) 框架介绍(2)

环境安装与配置 DRF需要以下依赖: Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6) Django (1.10, 1.11, 2.0) DRF是以Django扩展应用的方式提供的,所以我们可以直接利用已有的Django环境而无需从新创建.(若没有Django环境,需要先创建环境安装Django) 1. 安装DRF pip install djangorestframework 2. 添加rest_framework应用 我们利用在Django框架学习中创建的demo工

DRF (Django REST framework) 框架介绍

Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 1 前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口. 2 前后端分离 在前后端分离的应用模式中,后端仅返

DRF Django REST framework 之 认证组件(五)

引言 很久很久以前,Web站点只是作为浏览服务器资源(数据)和其他资源的工具,甚少有什么用户交互之类的烦人的事情需要处理,所以,Web站点的开发这根本不关心什么人在什么时候访问了什么资源,不需要记录任何数据,有客户端请求,我即返回数据,简单方便,每一个http请求都是新的,响应之后立即断开连接. 而如今,互联网的世界发生了翻天覆地的变化,用户不仅仅需要跟其他用户沟通交流,还需要跟服务器交互,不管是论坛类.商城类.社交类.门户类还是其他各类Web站点,大家都非常重视用户交互,只有跟用户交互了,才能

DRF Django REST framework 之 视图组件(四)

引言 在我们有几十上百的视图类,都有get,post等方法,在功能类似时,会导致大量的重复代码出现,显然还有很多可以优化的地方.这也就有了视图组件,它的功能非常强大,能很好的优化接口逻辑. 视图组件 使用视图组件的mixin优化接口逻辑 导入 mixins 定义序列化类 定义视图类 # 1.导入mixins from rest_framework.mixins import ( ListModelMixin, CreateModelMixin, DestroyModelMixin, Update

Django 【第九篇】自定义的分页器组件

一.分页的实现与使用 class Pagination(object): """ 自定义分页 """ def __init__(self,current_page,total_count,base_url,params,per_page_count=10,max_pager_count=11): try: current_page = int(current_page) except Exception as e: current_page =

Django Rest Framework源码剖析(八)-----视图与路由

一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使用者而言不同的视图具有不同的功能,这样我们可以根据需求定制自己视图.以下是官网传送门:http://www.django-rest-framework.org/api-guide/views/ 在之前的文章中,由于参杂了权限.认证等(如果不了解请看博客的以前的文章),但在本章中基本可以不使用,所进使

Django Restful Framework【第三篇】认证、权限、限制访问频率

一.认证 认证请求头 views.py #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BaseAuthentication from rest_framework.permissions import