心蓝的博客 心蓝的博客
首页
  • 零基础

    • python零基础入门
  • 专项

    • 正则表达式
  • web框架

    • django框架
    • drf
技术
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档

心蓝

人生苦短,我用python
首页
  • 零基础

    • python零基础入门
  • 专项

    • 正则表达式
  • web框架

    • django框架
    • drf
技术
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
  • 零基础

  • 专项

  • web框架

    • django框架

    • drf

      • 简介
      • 序列化器
      • 请求和响应
      • 类视图
      • 视图集和路由器
      • 序列化器补充
      • 身份验证与权限
      • 分页与限流
        • 分页
          • 分页设置
          • 修改分类样式
          • DRF内置分页类
          • PageNumberPagination
          • 使用
          • 配置
          • LimitOffsetPagination
          • 使用
          • 配置
        • 限流
          • 如何确定限流
          • 设置限流策略
          • 内置限流器
          • AnonRateThrottle
          • UserRateThrottle
          • ScopedRateThrottle
  • python
  • web框架
  • drf
心蓝
2022-12-26
目录

分页与限流

# 分页与限流

# 分页

对于大量数据的传输需要进行分页操作。

REST framework已经实现了分页api。它支持:

  • 将分页的链接作为响应内容的一部分,这是默认的方案。
  • 在响应头中包含分页链接,如Content-Range或Link。

注意只有在使用通用视图或视图集时,分页才会自动执行。如果你使用一个常规的APIView,你需要自己调用分页API来确保你返回一个分页的响应。

# 分页设置

REST framework中可以对分页功能进行全局设置,例如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 100
}
1
2
3
4

注意

需要同时设置DEFAULT_PAGINATION_CLASS和PAGE_SIZE,它们的默认值都为None,表示不使用分页。

还可以使用pagination_class属性在单个视图上设置分页类。

# 修改分类样式

如果希望修改分页样式的特定方面,则需要覆盖其中一个分页类,并设置要更改的属性。

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size'
    max_page_size = 10000

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 1000
1
2
3
4
5
6
7
8
9

然后你可以使用pagination_class属性将你的新样式应用到视图中:

class BillingRecordsView(generics.ListAPIView):
    queryset = Billing.objects.all()
    serializer_class = BillingRecordsSerializer
    pagination_class = LargeResultsSetPagination
1
2
3
4

当然也可以进行全局配置。

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
}
1
2
3

# DRF内置分页类

# PageNumberPagination

这是一个简单的页码分页类。

请求案例

GET https://api.example.org/accounts/?page=4
1

响应

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}
1
2
3
4
5
6
7
8
9
# 使用

同分页设置一样,全局使用配置如下:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100
}
1
2
3
4

也可以在GenericAPIView的子类通过在每个视图中设置pagination_class属性来应用分类。

# 配置

可以像上面一样复写下面的属性,来修改分类样式。

  • django_paginator_class - django框架分页类。默认使用django.core.paginator.Paginator。
  • page_size - 表示一页数据条数的数值。如果设置会覆盖设置中的PAGE_SIZE。
  • page_query_param - 一个字符串参数名,表示查询的页码,默认是page。
  • page_size_query_param - 一个字符串参数名,表示查询的每页数据数量。默认为None表示不能过客户端控制每页数据量。
  • max_page_size - 每页的最大数据量,和page_size_query_param配合使用。

# LimitOffsetPagination

这个分页类使用了数据库查询的语法。 客户端包含一个limit和一个offset查询参数。limit表示要返回的最大项数,与其他样式中的page_size相同。offset表示查询相对于完整的未分页项集的起始位置。

请求

GET https://api.example.org/accounts/?limit=100&offset=400
1

响应

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?limit=100&offset=500",
    "previous": "https://api.example.org/accounts/?limit=100&offset=300",
    "results": [
       …
    ]
}
1
2
3
4
5
6
7
8
9
# 使用

同分页设置一样,全局使用配置如下:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
  	'PAGE_SIZE': 100
}
1
2
3
4

也可以在GenericAPIView的子类通过在每个视图中设置pagination_class属性来应用分类。

# 配置

可以像上面一样复写下面的属性,来修改分类样式。

  • default_limit - 一个数字值,表示客户端在查询参数中未提供limit时所使用的值。默认值与PAGE_SIZE设置键相同。
  • limit_query_param - 一个字符串,表示limit参数的参数名,默认为limit
  • offset_query_param - 一个字符串,表示offset参数的参数名,默认为offset
  • max_limit - 如果设置,这是一个数字,表示最大允许客户端请求的limit,默认为None

# 限流

限流类似于权限,它决定是否应该授权请求。限流用于控制客户端可以向API发出的请求速率。与权限一样,可以使用多个限流。例如,对于未经身份验证的请求,你的API可能有一个严格的限流,而对于经过身份验证的请求,则不限制。

另一个可能需要使用多个节流的场景是,由于某些服务特别耗费资源,因此需要对API的不同部分施加不同的约束。

再比如,对突发访问和持续访问进行不同的限流,等等。

# 如何确定限流

与权限和身份验证一样,REST framework中的限流总是定义为一组类。

在运行视图主体之前,会检查列表中的每个限流器。如果任何限流检查失败,Throttled异常将被引发,并且视图的主体将不会运行。

# 设置限流策略

默认的节流策略可以全局设置,使用DEFAULT_THROTTLE_CLASSES和DEFAULT_THROTTLE_RATES设置。

例如:

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': '1000/day'
    }
}
1
2
3
4
5
6
7
8
9
10

DEFAULT_THROTTLE_RATES中使用的速率描述可以包括second、minute、hour或day作为限流周期。

也可以在在每个类视图或视图集的基础上通过throttle_classes属性来设置限流策略。

from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = [UserRateThrottle]
1
2
3
4
5
6

对于使用装饰器@api_view的函数视图,可以使用如下装饰器来进行限流:

@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)
1
2
3
4
5
6
7

# 内置限流器

# AnonRateThrottle

AnonRateThrottle只会限制未经认证的用户。

允许的请求率由以下其中一个决定(按优先顺序)。

  • 类上的rate属性,可以通过重写AnonRateThrottle并设置该属性来提供。
  • DEFAULT_THROTTLE_RATES['anon']设置

如果你想限制来自未知来源的请求的速率,AnonRateThrottle是合适的。

# UserRateThrottle

UserRateThrottle将限制经过验证的用户在API中给定的请求速率。

允许的请求率由以下其中一个决定(按优先顺序)。

  • 类上的rate属性,可以通过重写UserRateThrottle并设置该属性来提供。

  • DEFAULT_THROTTLE_RATES['user']设置

一个API可以同时有多个usererratethrottles。为此,重写UserRateThrottle并为每个类设置一个惟一的“作用域”。

例如:多个用户节流率可以通过使用以下类来实现…

class BurstRateThrottle(UserRateThrottle):
    scope = 'burst'

class SustainedRateThrottle(UserRateThrottle):
    scope = 'sustained'
1
2
3
4
5

然后设置如下

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'example.throttles.BurstRateThrottle',
        'example.throttles.SustainedRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'burst': '60/min',
        'sustained': '1000/day'
    }
}
1
2
3
4
5
6
7
8
9
10

如果您希望对每个用户进行简单的全局速率限制,那么UserRateThrottle是合适的。

# ScopedRateThrottle

ScopedRateThrottle类可用于限制对特定API的访问。

这个节流阀仅在被访问的视图包含.throttle_scope属性时才会被应用。

允许的请求速率由DEFAULT_THROTTLE_RATES设置决定。

例如,给出以下视图

class ContactListView(APIView):
    throttle_scope = 'contacts'
    ...

class ContactDetailView(APIView):
    throttle_scope = 'contacts'
    ...

class UploadView(APIView):
    throttle_scope = 'uploads'
    ...
1
2
3
4
5
6
7
8
9
10
11

然后设置如下:

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.ScopedRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'contacts': '1000/day',
        'uploads': '20/day'
    }
}
1
2
3
4
5
6
7
8
9

用户对ContactListView或ContactDetailView的请求将被限制为每天1000个请求。用户对UploadView的请求将被限制为每天20次。

本文完,感谢你的耐心阅读,如有需要可加我微信,备注「博客」并说明原因,我们一起进步,下次见。

#drf
上次更新: 2022/12/26, 16:59:39
身份验证与权限

← 身份验证与权限

最近更新
01
requests让接口测试如此简单 原创
03-31
02
最简明的python正则教程
03-30
03
pycharm激活码
12-30
更多文章>
Theme by Vdoing | Copyright © 2019-2025 心蓝
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式