关于 dmr-from-django-ninja
dmr-from-django-ninja 是将 django-ninja / ninja-extra API 传输层逐步迁移到 django-modern-rest 的开发 Skill,适用于希望保留业务逻辑和既有接口契约的 Django 项目。它强调逐端点核对行为、显式记录偏差,并使用项目已有的认证、限流和测试基础设施。
主要功能
- 01按端点分阶段迁移 API
- 02保持路由与请求响应契约
- 03迁移 DTO、控制器和路由配置
- 04检查并复用项目原生组件
- 05更新测试并运行 CI 验证
适用场景
- 01将 Ninja API 迁移至 DMR
- 02保留状态码、认证和限流语义
- 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.jsonagents/openai.yamlreferences/ninja-to-dmr-map.md详细介绍
从 django-ninja 迁移到 DMR
概述
逐步将 django-ninja / ninja-extra 传输层迁移到 django-modern-rest。
除非用户明确要求,否则业务逻辑保持不变。
必需文档(始终先参考):
- DMR LLM 文档:https://django-modern-rest.readthedocs.io/llms-full.txt
- 本地映射:references/ninja-to-dmr-map.md
迁移策略
- 默认模式:严格保持传输层一致性。
- 默认保留:路径、方法、请求/响应架构、状态码、标头、身份验证语义、限流语义。
- 如果用户批准偏差(例如切换到 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[...]、CookieCookies[...]。
- 请求体
- 当响应包含由服务器管理的字段时,拆分输入/输出 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 个部分报告:
preserved behaviorapproved driftunresolved 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.SchemaDTO。 - 已保留认证/限流行为,或明确批准行为差异。
- 已优先评估项目原生组件,并尽可能使用。
- 迁移后的传输层中不再保留持久化 Ninja 兼容层或绑定 Ninja 的命名。
- 仅在必要时更新测试,以保持所选策略下等效的行为覆盖。
- 已启用响应验证,且所有已迁移端点的响应均通过验证
(包括通过
ResponseSpec声明的额外响应)。 - 已按切片执行仓库原生 CI 入口。
- 已按要求的 3 部分格式输出最终报告。
- 成功完成迁移且迁移后的 API 表面通过 CI 后,除非用户明确批准保留,否则从项目依赖中移除 'django-ninja' 和 'ninja-extra'。
评论
支持 Markdown