django DRF 组件 限流

 

 

限流Throttling

可以对接口访问的频次进行限制,以减轻数据库的查询压力,或者实现特定的业务。

一般用于付费购买次数,投票等场景使用。

基本使用

可以在配置文件中,使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES进行全局配置,

 

"""drf的配置"""
# from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly
REST_FRAMEWORK = {
    # 配置认证方式的选项[全局配置]
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication', # session认证
        'rest_framework.authentication.BasicAuthentication',   # basic认证[基于账号密码]
    ],
    # 配置权限的选项[全局配置]
    # 'DEFAULT_PERMISSION_CLASSES': [
    #     'rest_framework.permissions.IsAuthenticated',  # 如果将来的站点时封闭内部系统,则设置IsAuthenticated
    #     # 'rest_framework.permissions.AllowAny',         # 如果将来的站点时开放外部系统,则设置AllowAny
    #     # 'rest_framework.permissions.IsAuthenticatedOrReadOnly',         # 如果将来的站点时开放外部系统,则设置AllowAny
    #     'component.permissions.VVIPPermission'
    # ],
    # 配置限流[全局配置]
    'DEFAULT_THROTTLE_CLASSES': [  # 限流配置类
        'rest_framework.throttling.AnonRateThrottle',  # 未登录认证的用户
        'rest_framework.throttling.UserRateThrottle',  # 已登录认证的用户
    ],
    'DEFAULT_THROTTLE_RATES': {  # 访问频率的全局配置
            'anon': '2/day',  # 针对游客的访问频率进行限制,实际上,drf只是识别首字母,但是为了提高代码的维护性,建议写完整单词
            'user': '5/day',  # 针对会员的访问频率进行限制,
        }
}

 

 

DEFAULT_THROTTLE_RATES限流配置可以支持使用 s(秒), m(分), h(时) 或d(天)来指明限流周期,对应的设置是在rest_framework/throttling.py的SimpleRateThrottle类中的parse_rate方法中设置的。源代码如下:

def parse_rate(self, rate):
        """
        Given the request rate string, return a two tuple of:
        <allowed number of requests>, <period of time in seconds>
        """
        if rate is None:
            return (None, None)
        num, period = rate.split('/')
        num_requests = int(num)
        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]]   # 核心代码
        return (num_requests, duration)

限流配置也可以在具体视图类中通过类属性throttle_classess来局部配置,views.py,代码:

from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class ThorttlingAPIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]
    def get(self,request):
        return Response("ok")

 

路由urls.py

# --- coding: utf-8 --
# @Date  : 2024/12/05
from django.urls import path, re_path
from . import views

urlpatterns = [
    path("auth/",views.AuthenticationAPIView.as_view()),
    path("pess/",views.PermissionAPIView.as_view({"get":"list","post":"create"})),
    re_path("^pess/(?P<pk>\d+)/$", views.PermissionAPIView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    path("throttle/", views.ThorttlingAPIView.as_view()),
]

 

setting.py

"""drf的配置"""
# from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly
REST_FRAMEWORK = {
    # 配置认证方式的选项[全局配置]
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication', # session认证
        'rest_framework.authentication.BasicAuthentication',   # basic认证[基于账号密码]
    ],
    # 配置权限的选项[全局配置]
    # 'DEFAULT_PERMISSION_CLASSES': [
    #     'rest_framework.permissions.IsAuthenticated',  # 如果将来的站点时封闭内部系统,则设置IsAuthenticated
    #     # 'rest_framework.permissions.AllowAny',         # 如果将来的站点时开放外部系统,则设置AllowAny
    #     # 'rest_framework.permissions.IsAuthenticatedOrReadOnly',         # 如果将来的站点时开放外部系统,则设置AllowAny
    #     'component.permissions.VVIPPermission'
    # ],
    # 配置限流[全局配置]
    # 'DEFAULT_THROTTLE_CLASSES': [  # 限流配置类
    #     'rest_framework.throttling.AnonRateThrottle',  # 未登录认证的用户
    #     'rest_framework.throttling.UserRateThrottle',  # 已登录认证的用户
    # ],
    'DEFAULT_THROTTLE_RATES': {  # 访问频率的全局配置
            'anon': '2/day',  # 针对游客的访问频率进行限制,实际上,drf只是识别首字母,但是为了提高代码的维护性,建议写完整单词
            'user': '5/day',  # 针对会员的访问频率进行限制,
        }
}

 

可选限流类

限流类  
AnonRateThrottle 限制所有匿名未认证用户,使用IP区分用户。 使用配置项DEFAULT_THROTTLE_RATES['anon'] 来设置频次
UserRateThrottle 限制认证用户,使用User模型的 id主键 来区分。 使用配置项DEFAULT_THROTTLE_RATES['user'] 来设置频次
ScopedRateThrottle 限制用户对于每个视图类的访问频次,使用ip或user id。 使用视图类中的throttle_scope设置限流频次的变量名,假设是a,则可以使用配置项DEFAULT_THROTTLE_RATES['a']来设置频次

settings.py,代码:

"""drf的配置"""
# from rest_framework.permissions import AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly
REST_FRAMEWORK = {
    # 配置认证方式的选项[全局配置]
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication', # session认证
        'rest_framework.authentication.BasicAuthentication',   # basic认证[基于账号密码]
    ],
    # # 配置权限的选项[全局配置]
    # 'DEFAULT_PERMISSION_CLASSES': [
    #     # 'rest_framework.permissions.IsAuthenticated',  # 如果将来的站点时封闭内部系统,则设置IsAuthenticated
    #     # 'rest_framework.permissions.AllowAny',         # 如果将来的站点时开放外部系统,则设置AllowAny
    #     'component.permissions.VVIPPermission'
    # ],
    # 配置限流[全局配置]
    'DEFAULT_THROTTLE_CLASSES':[ # 限流配置类
        # 'rest_framework.throttling.AnonRateThrottle',    # 未登录认证的用户
        # 'rest_framework.throttling.UserRateThrottle',    # 已登录认证的用户
        'rest_framework.throttling.ScopedRateThrottle',  # 已视图作为识别单位进行限流
    ],
    'DEFAULT_THROTTLE_RATES': {  # 频率配置
        'anon': '3/h',   # 针对游客的访问频率进行限制,实际上,drf只是识别首字母,但是为了提高代码的维护性,建议写完整单词
        'user': '10/h',  # 针对会员的访问频率进行限制,
        'thorttle': '5/h',  # 已视图中的throttle_scope进行设置限流频率
    }
}

 视图代码:

from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class ThorttlingAPIView(APIView):
    # throttle_classes = [UserRateThrottle, AnonRateThrottle]
    throttle_scope = "thorttle"

    def get(self,request):
        return Response("ok")

class Thorttling2APIView(APIView):
    # throttle_classes = [UserRateThrottle, AnonRateThrottle]
    throttle_scope = "thorttle"

    def get(self,request):
        return Response("ok")

 

urls.py,代码:

from django.urls import path, re_path
from . import views

urlpatterns = [
    path("auth/", views.AuthenticationAPIView.as_view()),
    path("pess/", views.PermissionAPIView.as_view({"get": "list", "post": "create"})),
    re_path("^pess/(?P<pk>\d+)/$", views.PermissionAPIView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    path("throttle/", views.ThorttlingAPIView.as_view()),
    path("throttle2/", views.Thorttling2APIView.as_view()),
]

 

 
posted @ 2025-06-24 15:06  minger_lcm  阅读(17)  评论(0)    收藏  举报