Migrate an existing Django API from django-ninja/ninja-extra to django-modern-rest while preserving routes, request/response contracts, auth, throttling, and test coverage. Use when replacing NinjaExtraAPI/api_controller/http_* handlers/ninja.Schema with dmr controllers/routers and typed DTOs.
70
85%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Migrate django-ninja / ninja-extra transport layer to django-modern-rest incrementally.
Keep business logic unchanged unless user explicitly asks.
Required docs (always reference first):
approved drift.NinjaExtraAPI, api_controller, http_get/http_post/..., ninja.Schema, ninja_jwt, Ninja exception handlers, Ninja throttles.django-ratelimit integration when it exists,
instead of wrapping Ninja throttles,Choose one and record it before edits:
strict parity:
approved DMR-native errors:
ninja.Schema with explicit typed DTOs compatible with DMR serializer.Body[...], query Query[...], path Path[...], headers Headers[...], cookies Cookies[...].Controller[...].NinjaExtraAPI with DMR router + Django URL include wiring.api:* names) unless drift approved.Retry-After) unless drift approved.validate_responses settings in local development and testing.ResponseSpec.unresolved gaps.ninja.testing.TestClient,
NinjaExtra helpers, Ninja URL setup fixtures) with repository-native
Django/DMR testing entrypoints.api_client, authed_api_client, token/auth fixtures),
but rebind them to the migrated DMR stack.pytest plugin wiring (conftest.py / plugin modules)
so migrated API tests no longer depend on Ninja-only fixtures or helpers.ResponseSpec metadata.django-ninja / ninja-extra imports from migrated
test modules unless explicitly approved as temporary drift.Do not mark slice done until:
django-ninja / ninja-extra classes in migrated slices unless explicitly approved by the user as temporary.Ninja...) in migrated transport code.At each meaningful checkpoint and at completion, report in 3 sections:
preserved behaviorapproved driftunresolved gapsunresolved gaps must include concrete files/endpoints and why unresolved.
django-ratelimit integration: do not pass method='ALL' as a string.
Use ratelimit.core.ALL (or equivalent tuple) or rate-limiting silently won't trigger.strict=True, JSON UUID strings can fail validation
(Input should be an instance of UUID). For request DTO fields that accept
UUID from JSON, allow parsing explicitly (for example field-level strict=False).extra='ignore' for input DTOs. Set input DTO config to
reject extra fields (for example extra='forbid').approved DMR-native errors mode, DB integrity failures may surface as
unhandled 500 if not mapped. Use DMR endpoint/controller error handling
(modify(error_handler=...) or controller-level handler) to keep predictable
client error behavior without reviving legacy Ninja payload shape..local/... from ad-hoc virtualenv/poetry runs), as format/lint
stages may scan and fail on them.ninja.Schema DTOs replaced for migrated endpoints.ResponseSpec).ebee1f2
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.