首页 / 资讯中心 / 文章详情

drf之分页:TaoToken 统一 Key 下 DRF 分页参数与限流配置实战

drf之分页:TaoToken 统一 Key 下 DRF 分页参数与限流配置实战 ★ FEATURED ARTICLE
1. DRF 分页到底解决什么问题为什么接口一多就必须上做 Django REST framework 接口只要列表数据超过几十条前端就会开始抱怨一次性返回全部数据页面卡、流量大、数据库压力也大。分页就是把这个大列表切成一小块一小块返回前端翻一页拿一页。DRF 自带三种分页器PageNumberPagination、LimitOffsetPagination、CursorPagination它们解决的是同一个问题但适用场景完全不同。我见过不少项目一开始图省事列表接口直接queryset Model.objects.all()返回数据量小的时候没事等表里几万条记录接口响应时间从几十毫秒涨到几秒前端还得自己 slice。这时候再回头加分页改动面就大了。所以分页这件事最好在写第一个列表接口时就定好策略。这篇内容聚焦三件事第一三种分页器在真实接口里怎么选、参数怎么调第二把分页配置和 TaoToken 统一 Key 的请求侧鉴权、限流串起来联调第三给出可以直接复制的 settings.py 配置、视图引用片段和 curl 验证命令让你照着做完就能核对响应结构。适合谁看正在写 DRF 列表接口、被分页参数和限流配置绕晕的后端同学已经用了 DRF 但分页器是默认配置、想搞清楚page_size_query_param和max_page_size区别的人以及需要把接口鉴权和分页一起联调、想有一套统一 Key 通道来管理请求的开发者。先说结论PageNumberPagination 适合后台管理类、需要显示总页数的场景LimitOffsetPagination 适合前端需要灵活控制偏移量的场景CursorPagination 适合数据量大、只做无限滚动、不要求跳页的场景。选错分页器后期改起来比想象中麻烦。2. TaoToken 统一 Key 前置准备把鉴权和限流通道先搭好在写分页配置之前先把请求侧的通道理清楚。分页本身是响应结构的控制但真实接口还要处理鉴权和限流。如果每个接口都自己写一套 Key 校验维护成本很高。TaoToken 提供统一 Key 和 API 通道把模型调用、编码类请求的鉴权收敛到一个入口分页接口联调时可以直接复用这套 Key。你需要先拿到一个可用的 API Key。进入控制台创建 Key路径是 console创建完成后在 api-keys 页面可以看到完整 Key 和对应的 Base URL。Base URL 用https://taotoken.net/api注意这个地址不带任何查询参数直接作为请求前缀使用。拿到 Key 之后建议先在模型对话页面做一次连通性验证确认 Key 有效、通道正常。这一步不是必须但能帮你排除后面分页联调时「到底是分页配置错了还是 Key 没生效」的干扰。模型对话入口可以直接测试请求是否返回正常结构。如果你后续要做长期编码或 Agent 类任务可以了解 Coding Plan它把编码场景的调用额度做了打包适合持续性的开发联调。但分页接口本身的鉴权用普通 API Key 就够了。这里要强调一点TaoToken 是请求侧的通道和 Key 管理不是替代 Django 或 DRF 的框架。分页逻辑仍然写在你的 DRF 项目里TaoToken 负责的是请求进来时的鉴权和限流这一层。两者是配合关系不是替代关系。配置顺序建议这样先在 settings.py 里配好 DRF 的分页类和默认分页器再在视图里引用具体分页类最后把请求侧的 Key 校验和限流接上。顺序反了容易在调试时分不清是哪一层出的问题。还有一个容易忽略的点分页参数是请求侧传进来的限流也是请求侧控制的。如果你的限流规则按 IP 或按 Key 来分页请求的page、limit、cursor参数都会走同一条通道。所以限流阈值要考虑到分页请求的频率——前端翻页可能一秒发好几个请求阈值设太低会误伤正常翻页。3. 可复制配置settings.py 分页类 视图引用 限流参数这一节给可直接复制的代码。先建一个pagination.py把三种分页类都写进去按需引用。# your_app/pagination.py from rest_framework.pagination import ( PageNumberPagination, LimitOffsetPagination, CursorPagination, ) class CommonPageNumberPagination(PageNumberPagination): page_size 10 page_query_param page page_size_query_param size max_page_size 100 class CommonLimitOffsetPagination(LimitOffsetPagination): default_limit 10 limit_query_param limit offset_query_param offset max_limit 100 class CommonCursorPagination(CursorPagination): cursor_query_param cursor page_size 10 ordering id然后在settings.py里配置 DRF 的默认分页器和限流# settings.py REST_FRAMEWORK { DEFAULT_PAGINATION_CLASS: your_app.pagination.CommonPageNumberPagination, PAGE_SIZE: 10, DEFAULT_THROTTLE_CLASSES: [ rest_framework.throttling.AnonRateThrottle, rest_framework.throttling.UserRateThrottle, ], DEFAULT_THROTTLE_RATES: { anon: 60/min, user: 300/min, }, }视图里引用具体分页类注意一个视图只能用一种分页方式# your_app/views.py from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin from your_app.models import Article from your_app.serializers import ArticleSerializer from your_app.pagination import ( CommonPageNumberPagination, CommonLimitOffsetPagination, CommonCursorPagination, ) class ArticlePageNumberView(ListModelMixin, GenericViewSet): queryset Article.objects.all().order_by(-id) serializer_class ArticleSerializer pagination_class CommonPageNumberPagination class ArticleLimitOffsetView(ListModelMixin, GenericViewSet): queryset Article.objects.all().order_by(-id) serializer_class ArticleSerializer pagination_class CommonLimitOffsetPagination class ArticleCursorView(ListModelMixin, GenericViewSet): queryset Article.objects.all().order_by(-id) serializer_class ArticleSerializer pagination_class CommonCursorPagination路由注册# your_app/urls.py from rest_framework.routers import DefaultRouter from your_app.views import ( ArticlePageNumberView, ArticleLimitOffsetView, ArticleCursorView, ) router DefaultRouter() router.register(articles/page, ArticlePageNumberView, basenamearticles-page) router.register(articles/limit, ArticleLimitOffsetView, basenamearticles-limit) router.register(articles/cursor, ArticleCursorView, basenamearticles-cursor) urlpatterns router.urls如果你用 Cline MCP 或 Claude Code 这类工具做联调配置里需要写全三件套Base URL 用https://taotoken.net/apiKey 用控制台创建的 KeyModel ID 按你实际调用的模型填。这三项缺一个都会导致请求失败。Codex 的auth.json里同样要保证 Base URL、Key、Model ID 三项完整格式按工具要求写。CursorPagination 有个硬性要求ordering必须指定而且不能是可变字段。上面用id是安全的。如果你用created_at要确保这个字段不会重复否则游标可能跳过或重复数据。4. 验证请求与成功结果curl 实测三种分页响应结构配置写完后用 curl 逐个验证。先启动 Django 服务假设跑在http://127.0.0.1:8000。PageNumberPagination 验证curl -s http://127.0.0.1:8000/articles/page/?page1size2 \ -H Authorization: Bearer YOUR_TAOTOKEN_KEY成功返回结构{ count: 25, next: http://127.0.0.1:8000/articles/page/?page2size2, previous: null, results: [ {id: 25, title: ...}, {id: 24, title: ...} ] }count是总数next和previous是翻页链接results是当前页数据。size2生效说明page_size_query_param配置正确如果传size200但只返回 100 条说明max_page_size100生效了。LimitOffsetPagination 验证curl -s http://127.0.0.1:8000/articles/limit/?limit2offset1 \ -H Authorization: Bearer YOUR_TAOTOKEN_KEY返回结构里count、next、previous、results都在但next链接会带limit和offset参数。offset1表示从第二条开始取取limit2条。CursorPagination 验证curl -s http://127.0.0.1:8000/articles/cursor/?cursorpage_size2 \ -H Authorization: Bearer YOUR_TAOTOKEN_KEY第一次请求cursor传空返回里会带next链接里面包含一个编码后的 cursor 值。第二次请求把那个 cursor 值原样带上curl -s http://127.0.0.1:8000/articles/cursor/?cursorcD0ypage_size2 \ -H Authorization: Bearer YOUR_TAOTOKEN_KEY游标分页的返回结构里没有count也没有previous只有next和results。这是它的设计特点不告诉你总数只告诉你下一页怎么走。如果你需要显示总页数游标分页做不到得换 PageNumberPagination。限流验证连续快速发 70 次匿名请求超过60/min后应该返回 429for i in $(seq 1 70); do curl -s -o /dev/null -w %{http_code}\n \ http://127.0.0.1:8000/articles/page/?page1 done看到 429 说明限流生效。带 Key 的请求走user限流阈值是300/min比匿名高这是合理的——已鉴权用户应该获得更高配额。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth联调时最容易撞上的几类报错逐个说清楚。401 Unauthorized请求头里 Key 没带、带错、或者格式不对。检查Authorization: Bearer YOUR_KEY这一行Bearer 后面有一个空格Key 不能有多余换行。如果 Key 是从控制台复制的注意别把前后空格带进去。还有一种情况是 Key 已过期或被删除去 api-keys 页面确认状态。local proxy failed这个报错通常出现在本地联调工具或客户端配置里意思是请求没能到达目标地址。检查 Base URL 是否写成了https://taotoken.net/api有没有多写路径或少了/api。如果你在工具里配了额外的转发规则先去掉用最简配置试。这个报错和分页配置无关是通道层的问题。reading choices 相关报错这类报错一般出现在响应解析阶段比如客户端期望results字段但实际返回的是裸列表。原因通常是视图没有正确引用pagination_class或者DEFAULT_PAGINATION_CLASS没生效。检查视图类里pagination_class是否写对以及 settings 里的路径字符串是否和实际模块路径一致。路径写错时 DRF 会静默回退到默认行为不报错但结构不对。OAuth 相关报错如果你用的是需要 OAuth 流程的工具或客户端报错通常指向 token 获取失败。检查 OAuth 配置里的回调地址、client id、client secret 是否和平台一致。分页接口本身不涉及 OAuth但如果你的请求通道走了 OAuth 鉴权这一步没过后面的分页请求根本发不出去。建议先用最简单的 Bearer Key 方式验证分页确认分页逻辑没问题后再切到 OAuth 通道。还有一个隐蔽的坑CursorPagination 的ordering字段如果和 queryset 的order_by不一致游标会乱跳。比如分页类里写ordering id但视图 queryset 写.order_by(-created_at)两者冲突时以分页类的ordering为准但数据顺序可能和你预期不同。统一用同一个字段排序别混用。限流误伤也是常见问题前端翻页快anon阈值60/min可能不够。如果接口是公开的、前端会连续翻页把anon调到120/min或更高或者要求前端带 Key 走user限流。阈值没有标准答案按实际请求频率调。6. 分页选型与请求通道的配合建议三种分页器没有绝对优劣只有场景匹配。后台管理列表、需要显示「第 3 页 / 共 20 页」的用 PageNumberPagination前端有「加载更多」但需要精确控制偏移的用 LimitOffsetPagination数据量大、只做无限滚动、不关心总数的用 CursorPagination。请求通道这边统一 Key 的好处是所有分页接口共用一套鉴权和限流规则不用每个视图单独写。分页参数调试阶段建议先用模型对话页面确认 Key 和通道正常再回到本地接口调分页。这样出问题时能快速定位是通道层还是分页层。长期做编码联调的话Coding Plan 把额度打包省去每次单独配 Key 的麻烦。但分页接口的日常调试普通 API Key 加接入文档里的示例就够了。文档里有各语言请求示例照着改 Base URL 和 Key 就能跑。最后提醒一句分页配置改完后一定要用 curl 实际请求一次核对count、next、results三个字段是否符合预期。光看代码不验证很容易漏掉路径写错、参数名拼错这类低级问题。
阅读完成 · 觉得有帮助?
咨询建站