关于 dmr
dmr 是面向 Django Modern REST 开发的编码 Agent 技能,指导控制器、类型化请求组件、路由、安全和 OpenAPI 的实现与审查。它强调按已安装版本查阅文档,并提供测试与迁移相关工作流。
主要功能
- 01指导控制器与请求组件设计
- 02同步与异步端点检查
- 03路由、认证与节流指导
- 04类型生成 OpenAPI
- 05代码审查与测试清单
适用场景
- 01开发 Django REST API
- 02审查现有 dmr 代码
- 03验证端点与 OpenAPI 变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ wemake-services/ django-modern-rest --skill dmr安装后在 Claude Code 中输入/dmr确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.claude-plugin/plugin.jsonagents/openai.yamlreferences/controllers.mderrors.mdopenapi.mdrouting.mdsecurity.mdtesting.mdvalidation.md详细介绍
django-modern-rest (dmr)
django-modern-rest 是 Django 的类型化、同步与异步 REST 层:
使用 Controller 类为每种 HTTP 动词提供一个方法,使用从
Body、Query、Headers、Cookies 和 Path 注解解析的 DTO,
基于 Router 的 URL,内置身份验证和限流,
并根据类型生成 OpenAPI。
适用场景
- 导入
dmr的任何文件,或依赖项中包含django-modern-rest的项目。 - 有关 Django REST API 的“类型化”“现代”或“异步”请求。
- 审查现有的
dmr代码:使用末尾的检查清单。
从其他框架迁移时,请使用 dmr-from-drf、
dmr-from-django-ninja 或 dmr-from-dj-rest-auth。
升级版本时,请使用 dmr-upgrade。
根据 OpenAPI 文档生成脚手架时,请使用 dmr-openapi-skeleton。
工作流
- 检查已安装的版本和额外依赖项:
uv pip show django-modern-rest(或检查锁定文件)。 API 会随次要版本更新,因此请阅读与已安装版本对应的文档, 而不是最新版本的文档。 - 加载所需文档,这些文档按版本分类,并针对 LLM 进行了优化:
- 索引:
https://django-modern-rest.readthedocs.io/en/<version>/llms.txt - 单页 Markdown:将任意文档 URL 中的
.html替换为.md, 例如https://django-modern-rest.readthedocs.io/en/latest/pages/routing.md - 一次性获取全部内容:
https://django-modern-rest.readthedocs.io/en/<version>/llms.txt
- 索引:
- 阅读要修改领域的参考文档 (参见下表),其中包含完整规则以及正确和错误示例。
- 验证:运行
python manage.py check、项目的类型检查器, 以及使用dmr_client/dmr_rffixture 编写的测试。 对于 OpenAPI 变更,运行python manage.py dmr_export_schema <path>并检查差异。
不可妥协的规则
即使是 pydantic 项目,也要安装 django-modern-rest[msgspec],
它能让 JSON 解析速度最快。将 django-stubs[compatible-mypy]
添加到开发依赖中,dmr 依赖 Django 类型。
组件参数必须准确命名为 parsed_body、parsed_query、
parsed_headers、parsed_path 和 parsed_cookies。
其他名称会被静默地跳过解析:
class UserController(Controller[MsgspecSerializer]):
def post(self, parsed_body: Body[UserModel]) -> UserModel:
return parsed_body
可选组件要在注解中保留 None:
parsed_body: Body[UserModel | None] = None。
Body[UserModel] | None = None 会在导入时出错。
绝不要使用 return HttpResponse(...),因为这会绕过协商、
请求头、Cookie 和验证。
在控制器中改用 self.to_response(...) 或 self.to_error(...)。
错误要抛出 APIError,
并在 handle_error / handle_async_error 中处理,而不是在端点主体中处理:
raise APIError(
self.format_error('Not found', error_type=ErrorType.user_msg),
status_code=HTTPStatus.NOT_FOUND,
)
优先使用 @modify 风格的端点,而非 @validated 风格的端点。
默认使用普通方法。只有在需要设置状态码、
请求头、Cookie、身份验证、限流,或需要添加不同于推断结果的额外响应时,才添加 @modify(...)。只有在端点有意返回 HttpResponse 时,才使用 @validate(ResponseSpec(...))。
优先使用 MsgspecSerializer。在仅使用 pydantic 和 JSON 时,
优先使用 PydanticFastSerializer,而非 PydanticSerializer。
使用 MsgspecSerializer 且所有端点解析器都解码为模型时,
例如 MsgspecJsonParser 和 MsgpackParser,
优先使用 BodyMsgspec,而非 Body。
使用 dmr.routing.path 和 Router,并安装
build_404_handler / build_500_handler,确保 API 错误以 JSON 格式返回。
如果使用 CSRF 且设置了 csrf_exempt = False,始终设置
CSRF_FAILURE_VIEW = build_csrf_handler(router.prefix, ...)
错误处理器。
确保同步与异步配置匹配:同步端点使用同步错误处理器和身份验证, 异步端点使用异步版本。在身份验证前对登录端点限流。
通过 concrete_views 路由身份验证端点,并使用 as_view(serializer=...),
不要仅为了重新声明默认载荷和响应而继承 dmr.security.*.views 控制器。
只有当载荷、响应或钩子不同时,才继承 views:
path(
'auth/',
concrete_views.ObtainTokensSyncController.as_view(
serializer=MsgspecSerializer,
),
)
as_view 会静默忽略 throttling= 和 auth=。具体视图
使用 Settings.throttling;登录专用限流需要 views 子类。
单元测试使用 dmr_rf(DMRRequestFactory),全栈测试使用
dmr_client(DMRClient),使用 polyfactory 生成载荷,
并使用 schemathesis 对 OpenAPI 架构进行测试。
快速参考
| 主题 | 规则 | 阅读 |
|---|---|---|
控制器、@modify 与 @validate、序列化器、响应、组件、重定向 | 9 | references/controllers.md |
| 路由、404 / 500 处理器、同步和异步应用布局 | 4 | references/routing.md |
错误处理器、APIError、自定义 error_model | 4 | references/errors.md |
响应验证、HttpSpec、设置 | 5 | references/validation.md |
可直接使用的身份验证 concrete_views、带类型的已验证身份请求、限流、wrap_middleware | 4 | references/security.md |
pytest 风格、DMRClient、DMRRequestFactory、polyfactory、schemathesis | 5 | references/testing.md |
| 将文档字符串用作 OpenAPI 描述 | 1 | references/openapi.md |
每条规则都链接到对应的说明文档页面。
审查清单
审查 dmr 代码时,请标记以下问题:
- 组件参数的名称不是
parsed_*。 - 使用
Body[Model] | None = None,而不是Body[Model | None] = None。 - 端点返回
HttpResponse(...)或JsonResponse(...)。 - 在端点主体中使用
try/except返回错误响应。 @modify或@validate与默认值相比没有任何改动。- 在错误处理器中使用
isinstance(exc, APIError)。 - 在生产设置之外使用
validate_responses = False,禁用semantic_responses,或使用空的解析器 / 渲染器。 - 异步控制器使用同步的
handle_error,或反之。 - 在登录端点上使用
RemoteAddr(runs_before_auth=False)。 dmr.security.*.views中的身份验证控制器子类保留默认负载和响应, 且对应的concrete_views也如此。- Cookie 的
concrete_views未设置jwt_refresh_cookie_path, 导致每个请求都会发送刷新令牌。 - 将
throttling=、auth=或responses=传递给as_view(), 这些参数会被静默忽略。 - 对用户提供的 URL 使用
RedirectTo(next_url),但未检查url_has_allowed_host_and_scheme。 - 使用
django.urls.path,而dmr.routing.path可以直接替代它。 - 使用
django.test.TestCase、RequestFactory或Client, 而dmr_rf/dmr_client夹具已存在。 - 在提供 OpenAPI 时,控制器和端点没有文档字符串。