mcpField
D
dmr-from-django-ninja

dmr-from-django-ninja

github.com/wemake-services开发1.5k40 次安装今天更新
代码仓库

关于 dmr-from-django-ninja

dmr-from-django-ninja 是将 django-ninja / ninja-extra API 传输层逐步迁移到 django-modern-rest 的开发 Skill,适用于希望保留业务逻辑和既有接口契约的 Django 项目。它强调逐端点核对行为、显式记录偏差,并使用项目已有的认证、限流和测试基础设施。

主要功能

  1. 01按端点分阶段迁移 API
  2. 02保持路由与请求响应契约
  3. 03迁移 DTO、控制器和路由配置
  4. 04检查并复用项目原生组件
  5. 05更新测试并运行 CI 验证

适用场景

  1. 01将 Ninja API 迁移至 DMR
  2. 02保留状态码、认证和限流语义
  3. 03分批改造并验证 Django API

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wemake-services/django-modern-rest --skill dmr-from-django-ninja

安装后在 Claude Code 中输入/dmr-from-django-ninja确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.claude-plugin/
plugin.json
agents/
openai.yaml
references/
ninja-to-dmr-map.md

详细介绍

从 django-ninja 迁移到 DMR

概述

逐步将 django-ninja / ninja-extra 传输层迁移到 django-modern-rest。 除非用户明确要求,否则业务逻辑保持不变。

必需文档(始终先参考):

迁移策略

  • 默认模式:严格保持传输层一致性。
  • 默认保留:路径、方法、请求/响应架构、状态码、标头、身份验证语义、限流语义。
  • 如果用户批准偏差(例如切换到 DMR 原生错误格式/状态码),则停止强制保留旧行为,并将其记录为 approved drift。
  • 绝不混入隐式偏差:每项有意的不一致都必须明确列出。
  • 不要将 Ninja 基础设施内部实现作为实施策略保留下来。 保留可观察到的契约,但使用 DMR + 项目原生库来实现。

工作流

清点 Ninja 接口
  • 首先阅读项目 API 入口和 URL 配置。
  • 查找以下内容的用法:NinjaExtraAPI、api_controller、http_get/http_post/...、ninja.Schema、ninja_jwt、Ninja 异常处理器、Ninja 限流器。
  • 为每个端点建立迁移矩阵:
    • 路径、方法、身份验证、限流、输入 DTO、输出 DTO,
    • 预期状态码、预期标头,
    • 已知错误路径。
清点项目原生工具(必需)
  • 编写适配器前,检查现有项目库和集成,确定哪些应为迁移后的传输层提供支持。
  • 优先通过 DMR 机制使用项目已有的库(“Django 工具”),而不是自定义封装。
  • 示例:
    • 限流:如果已有 django-ratelimit 集成,优先使用它, 而不是封装 Ninja 限流器;
    • 身份验证/账户锁定:优先使用现有项目身份验证栈(例如 axes/中间件), 而不是复用 Ninja 特有的身份验证内部实现。
冻结可观察行为
  • 根据现有测试 + DTO + 路由,记录当前行为。
  • 编码前标记阻塞性不一致:
    • 路由/方法变更,
    • 架构字段变更,
    • 身份验证/限流变更,
    • 状态码/标头变更。
确定错误策略(必需关卡)

选择一项并在修改前记录:

  • strict parity:
    • 保留现有错误状态码/负载语义,
    • 根据需要适配 DMR 处理器/上下文。
  • approved DMR-native errors:
    • 使用框架原生错误映射,
    • 相应更新测试和文档预期,
    • 仍保留正常请求行为以及身份验证/限流行为。
按切片迁移(应用或端点组)
  • 每次迁移一个范围明确的切片。
  • 除非架构/lint 契约要求变更,否则保持模块布局不变。
  • 不要保留体现 Ninja 基础设施的类名。 将传输类重命名为中性名称或面向 DMR 的名称。
  • 优先采用轻量传输适配器:
    • 不改动用例/服务/仓储,
    • 只修改 DTO/控制器/路由配置。
转换 DTO 和组件
  • 将 ninja.Schema 替换为与 DMR 序列化器兼容的显式类型化 DTO。
  • 明确映射请求来源:
    • 请求体 Body[...]、查询参数 Query[...]、路径参数 Path[...]、标头 Headers[...]、Cookie Cookies[...]。
  • 当响应包含由服务器管理的字段时,拆分输入/输出 DTO。
将处理器迁移到 DMR
  • 单一操作:Controller[...]。
  • 多方法路径:控制器 + 组合。
  • 除非用户要求偏差,否则保持路由名称和 URL 结构稳定。
  • 有意迁移异常行为:
    • 严格保持一致模式:保留旧状态码/负载;
    • 批准偏差模式:保留 DMR 原生错误并更新测试。
替换 API 配置
  • 将 NinjaExtraAPI 替换为 DMR 路由器 + Django URL include 配置。
  • 除非批准偏差,否则保持命名空间稳定(api:* 名称)。
  • 仅当项目已公开文档/OpenAPI 路由时才添加这些路由。
使用原生工具处理身份验证和限流
  • 按端点保留身份验证预期。
  • 保留限流行为和标头(例如 Retry-After),除非已批准偏差。
  • 优先通过 DMR 钩子使用项目现有的原生身份验证/限流库。
  • 在本地开发和测试中始终启用全局 validate_responses 设置。
  • 确保使用 ResponseSpec 显式声明所有额外响应。
  • 要求所有响应都通过响应验证。
  • 避免将 Ninja 兼容性垫片作为最终方案。 如果无法避免使用临时垫片,请明确标记为临时方案, 记录替换计划,并将其列入 unresolved gaps。
更新 DMR 工具的测试
  • 将 Ninja 专用测试工具(ninja.testing.TestClient、 NinjaExtra 辅助工具、Ninja URL 设置夹具)替换为仓库原生的 Django/DMR 测试入口。
  • 将 API 测试夹具和客户端作为一等迁移范围: 保持夹具的用途不变(api_client、authed_api_client、令牌/身份验证夹具), 但将其重新绑定到迁移后的 DMR 技术栈。
  • 审核并更新 pytest 插件配置(conftest.py/插件模块), 确保迁移后的 API 测试不再依赖 Ninja 专用夹具或辅助工具。
  • 按端点保留契约断言: 状态码、负载、标头、身份验证行为、限流行为。
  • 确保负向路径测试覆盖已声明的额外响应,并与 ResponseSpec 元数据一致。
  • 除非明确批准作为临时偏差,否则从已迁移的测试模块中移除持久存在的 django-ninja/ninja-extra 导入。
使用仓库原生 CI 入口验证每个迁移切片
  • 运行本仓库 CI 使用的相同命令。
  • 优先使用官方脚本入口,而不是临时拼凑的命令集。
  • 如果需要仅限 Docker 的 CI/测试环境,请在 Docker 中运行。
完成门槛

满足以下条件后,才能将迁移切片标记为完成:

  • 代码检查通过,
  • 测试通过(或明确批准测试失败为偏差),
  • 报告已更新。

翻译规则

  • 默认不更改业务逻辑。
  • 保持传输行为确定且类型明确。
  • 避免隐式路由规范化更改(尾部斜杠/前缀)。
  • 即使错误负载格式发生偏差,也要保留身份验证和限流语义。
  • 明确说明框架约束(例如 DMR 原生验证行为)。
  • 除非用户明确批准作为临时方案,否则不要在已迁移的切片中使用 django-ninja/ninja-extra 类。
  • 不要在已迁移的传输代码中保留绑定到 Ninja 的类名(例如以 Ninja... 为前缀的名称)。

报告格式(必需)

在每个重要检查点和完成时,分为以下 3 个部分报告:

  1. preserved behavior
  2. approved drift
  3. unresolved gaps

unresolved gaps 必须包含具体文件/端点以及未解决的原因。

迁移陷阱(基于仓库)

  • django-ratelimit 集成:不要将 method='ALL' 作为字符串传入。 请使用 ratelimit.core.ALL(或等效元组),否则限流不会触发,且不会发出提示。
  • 如果基础 Pydantic 配置使用 strict=True,JSON UUID 字符串可能会验证失败 (Input should be an instance of UUID)。对于接受 JSON UUID 的请求 DTO 字段,请显式允许解析(例如在字段级别设置 strict=False)。
  • 如果要保留严格的输入架构(必须拒绝未知字段),不要依赖带有 extra='ignore' 的基础模型来处理输入 DTO。请将输入 DTO 配置为拒绝额外字段(例如设置 extra='forbid')。
  • 在 approved DMR-native errors 模式下,如果未映射数据库完整性错误,它们可能会作为未处理的 500 错误暴露。请使用 DMR 端点/控制器错误处理(modify(error_handler=...) 或控制器级处理程序),在不恢复旧版 Ninja 负载格式的情况下,保持客户端错误行为可预测。
  • CI 卫生:避免运行会生成项目本地工具产物的调试命令(例如通过临时 virtualenv/poetry 运行生成的 .local/...),因为格式化/代码检查阶段可能会扫描这些文件并因此失败。

输出检查清单

  • 已将 Ninja 根路由替换为 DMR 路由。
  • 已将 Ninja 控制器/处理器替换为 DMR 控制器。
  • 已替换已迁移端点的 ninja.Schema DTO。
  • 已保留认证/限流行为,或明确批准行为差异。
  • 已优先评估项目原生组件,并尽可能使用。
  • 迁移后的传输层中不再保留持久化 Ninja 兼容层或绑定 Ninja 的命名。
  • 仅在必要时更新测试,以保持所选策略下等效的行为覆盖。
  • 已启用响应验证,且所有已迁移端点的响应均通过验证 (包括通过 ResponseSpec 声明的额外响应)。
  • 已按切片执行仓库原生 CI 入口。
  • 已按要求的 3 部分格式输出最终报告。
  • 成功完成迁移且迁移后的 API 表面通过 CI 后,除非用户明确批准保留,否则从项目依赖中移除 'django-ninja' 和 'ninja-extra'。

评论

支持 Markdown