dmr について
dmr は django-modern-rest を使った Django REST API の開発・レビュー向けコーディングエージェントスキルです。型付きコントローラー、ルーティング、セキュリティ、OpenAPI と、導入バージョンに応じたドキュメント参照を案内します。
主な機能
- 01コントローラーとリクエスト要素の設計案内
- 02同期・非同期エンドポイントの確認
- 03ルーティング、認証、スロットリングの案内
- 04型からの OpenAPI 生成
- 05コードレビューとテストのチェックリスト
活用シーン
- 01Django 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 レイヤーです。
HTTP 動詞ごとにメソッドを持つ Controller クラス、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_rfフィクスチャを使ったテストを実行します。 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,
)
@validated スタイルのエンドポイントよりも、@modify スタイルのエンドポイントを優先してください。
デフォルトでは通常のメソッドを使用してください。ステータスコード、
ヘッダー、Cookie、認証、スロットリング、または追加レスポンスが推論されたものと
異なる場合に限り、@modify(...) を追加してください。エンドポイントが意図的に
HttpResponse を返す場合に限り、@validate(ResponseSpec(...)) を使用してください。
MsgspecSerializer を優先してください。pydantic を使用し、JSON のみを扱う場合は、
PydanticSerializer よりも PydanticFastSerializer を優先してください。
MsgspecSerializer を使用し、すべてのエンドポイントパーサーが
MsgspecJsonParser や MsgpackParser のようにモデルへデコードする場合は、
Body よりも BodyMsgspec を優先してください。
dmr.routing.path と Router を使用し、
API エラーが JSON になるよう build_404_handler / build_500_handler を設定してください。
CSRF と csrf_exempt = False を使用する場合は、
必ずエラーハンドラー CSRF_FAILURE_VIEW = build_csrf_handler(router.prefix, ...) を設定してください。
開発環境とテストでは validate_responses を有効にし、本番環境の設定でのみ無効にしてください。
semantic_responses は絶対に無効にせず、空の parsers や renderers を設定しないでください。
同期と非同期を一致させてください。同期エンドポイントには同期のエラーハンドラーと認証を、 非同期エンドポイントには非同期のものを使用してください。ログインエンドポイントは認証の前にスロットリングしてください。
認証エンドポイントは、concrete_views から as_view(serializer=...) でルーティングしてください。
デフォルトのペイロードとレスポンスを再記述するだけの目的で、
dmr.security.*.views のコントローラーをサブクラス化しないでください。
サブクラス化するのは、ペイロード、レスポンス、またはフックが異なる場合に限ってください。
path(
'auth/',
concrete_views.ObtainTokensSyncController.as_view(
serializer=MsgspecSerializer,
),
)
as_view は throttling= と auth= を無視します。具体ビューでは
Settings.throttling が使用されます。ログイン専用のスロットリングが必要な場合は、
views のサブクラスが必要です。
単体テストには dmr_rf(DMRRequestFactory)を、フルスタックテストには
dmr_client(DMRClient)を使用してください。ペイロードの生成には polyfactory を、
OpenAPI スキーマに対するテストには schemathesis を使用してください。
クイックリファレンス
| トピック | ルール | 参照先 |
|---|---|---|
コントローラー、@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 の説明としての docstring | 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対応クラスも同様になっている。 jwt_refresh_cookie_pathのない Cookieconcrete_viewsがあり、リフレッシュトークンがすべてのリクエストで送信される。as_view()に渡されたthrottling=、auth=、またはresponses=は、そこで暗黙的に無視される。- ユーザー指定の URL を使う
RedirectTo(next_url)があり、url_has_allowed_host_and_schemeによるチェックがない。 dmr.routing.pathがそのまま置き換えられるにもかかわらず、django.urls.pathを使っている。dmr_rf/dmr_clientフィクスチャがあるにもかかわらず、django.test.TestCase、RequestFactory、またはClientを使っている。- OpenAPI が公開されているのに、コントローラーとエンドポイントに docstring がない。