{"id":7173,"library":"django-ninja-extra","title":"Django Ninja Extra","description":"Django Ninja Extra is a powerful extension for Django Ninja, providing class-based utilities and advanced features for building REST APIs. It augments Django Ninja with API controllers, an advanced permission system (similar to Django REST Framework), dependency injection, and a service layer for business logic. The library is actively maintained, with its current version being 0.31.4, and follows a frequent release cadence to support the latest Django and Django Ninja versions.","status":"active","version":"0.31.4","language":"en","source_language":"en","source_url":"https://github.com/eadwinCode/django-ninja-extra","tags":["Django","REST API","Pydantic","Class-based views","API controllers","Dependency Injection","OpenAPI"],"install":[{"cmd":"pip install django-ninja-extra","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Core Django framework requirement.","package":"django","optional":false},{"reason":"Django Ninja Extra is an extension built on top of Django Ninja.","package":"django-ninja","optional":false},{"reason":"Used by Django Ninja for data validation and serialization.","package":"pydantic","optional":false},{"reason":"Often used with ModelController for automatic schema generation from Django ORM models.","package":"ninja-schema","optional":true}],"imports":[{"note":"While NinjaExtraAPI inherits from NinjaAPI, directly importing NinjaAPI will miss extra features.","wrong":"from ninja import NinjaAPI","symbol":"NinjaExtraAPI","correct":"from ninja_extra import NinjaExtraAPI"},{"note":"Decorator for defining class-based API controllers.","symbol":"api_controller","correct":"from ninja_extra import api_controller"},{"note":"HTTP method decorator for controller methods (e.g., @http_get).","symbol":"http_get","correct":"from ninja_extra import http_get"},{"note":"Base class for generating CRUD operations for Django models.","symbol":"ModelControllerBase","correct":"from ninja_extra import ModelControllerBase"},{"note":"Base class for defining custom service logic for ModelControllers.","symbol":"ModelService","correct":"from ninja_extra import ModelService"}],"quickstart":{"code":"import os\nfrom django.conf import settings\nfrom django.urls import path\nfrom ninja_extra import NinjaExtraAPI, api_controller, http_get\n\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        INSTALLED_APPS=[\n            'django.contrib.auth',\n            'django.contrib.contenttypes',\n            'ninja_extra',\n        ],\n        ROOT_URLCONF=__name__,\n        SECRET_KEY='a-very-secret-key',\n        TEMPLATES=[{\n            'BACKEND': 'django.template.backends.django.DjangoTemplates',\n            'APP_DIRS': True,\n        }],\n    )\n\napi = NinjaExtraAPI()\n\n@api_controller(\"/items\", tags=[\"Items\"])\nclass ItemController:\n    @http_get(\"/\")\n    def list_items(self):\n        return [{\"id\": 1, \"name\": \"Item 1\"}, {\"id\": 2, \"name\": \"Item 2\"}]\n\n    @http_get(\"/{item_id}\")\n    def get_item(self, item_id: int):\n        return {\"id\": item_id, \"name\": f\"Item {item_id}\"}\n\napi.register_controllers(ItemController)\n\nurlpatterns = [\n    path(\"api/\", api.urls),\n]\n\n# To run this in a Django project, you'd integrate `api.urls` into your project's `urls.py`:\n# from django.urls import path, include\n# from .api import api # Assuming your api setup is in api.py\n# urlpatterns = [\n#     path(\"api/\", api.urls),\n# ]\n# Remember to add 'ninja_extra' to your INSTALLED_APPS in settings.py","lang":"python","description":"This quickstart demonstrates how to set up a basic API using `NinjaExtraAPI` and define a class-based `APIController` with two simple GET routes. It includes the necessary Django setup for a runnable example. The controller is registered with the main API instance, and its routes are then exposed via Django's URL configuration. Remember to add 'ninja_extra' to your `INSTALLED_APPS`."},"warnings":[{"fix":"Review the Pydantic v2 migration guide (https://pydantic.dev/latest/migration/) and update your schemas and configuration accordingly. Ensure all Pydantic-related code adheres to v2 standards.","message":"Version 0.30.9 introduced a migration from Pydantic v1 config to Pydantic v2 config. This is a significant breaking change if your project relies on Pydantic v1 specific syntax or behaviors.","severity":"breaking","affected_versions":">=0.30.9"},{"fix":"Replace calls to `api.get_api_controller(YourController)` with `api.api_controller[YourController]` or access it directly if already registered. For example, `api.api_controller[ItemController].list_items()`.","message":"The `get_api_controller()` method has been deprecated and replaced by the `api_controller` property for accessing controller instances within the API.","severity":"deprecated","affected_versions":">=0.31.2"},{"fix":"If defining a custom ModelService for a ModelController, specify it using `service_type = YourCustomModelService` instead of directly assigning to `service`.","message":"In versions prior to 0.22.2, the `service` attribute in `ModelController` was expected to be a class object. It was changed to an instance object, requiring `service_type` to be specified.","severity":"breaking","affected_versions":"<0.22.2 to 0.22.2+"},{"fix":"Upgrade to `django-ninja-extra` version 0.31.3 or higher to ensure proper inheritance of API-level authentication and throttling. Manually apply auth/throttle decorators to individual routes as a workaround for older versions.","message":"Prior to versions 0.31.3/0.31.4, there were issues with API-level authentication and throttling not correctly inheriting to controller routes.","severity":"gotcha","affected_versions":"<0.31.3"},{"fix":"This issue was largely resolved with the Pydantic v2 migration in 0.30.9. Ensure your `django-ninja-extra` and `pydantic` versions are up-to-date and compatible. If still encountering, try pinning `pydantic` to a compatible v1 version (e.g., `pydantic<2.0,>=1.10`) for older `django-ninja-extra` versions.","message":"An MRO (Method Resolution Order) bug might occur with `PaginatedResponseSchema` when using `django-ninja-extra>=0.21` in combination with specific Pydantic versions, causing `TypeError: Cannot create a consistent method resolution order (MRO)`.","severity":"gotcha","affected_versions":">=0.21, <0.30.9"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"This specific MRO issue was largely addressed with the Pydantic v2 migration in `django-ninja-extra>=0.30.9`. Ensure you are on the latest compatible versions of `django-ninja-extra` and `pydantic`. If on an older `django-ninja-extra` version, try pinning `pydantic` to `pydantic<2.0,>=1.10.0`.","cause":"Incompatible inheritance hierarchy, often due to a specific interaction between django-ninja-extra's PaginatedResponseSchema and certain Pydantic versions.","error":"TypeError: Cannot create a consistent method resolution order (MRO) for bases PaginatedResponseSchema, Generic"},{"fix":"Ensure the controller method is decorated with the correct HTTP verb decorator for the request you are making (e.g., `@http_post`, `@http_put`, `@http_delete`).","cause":"Attempting an HTTP method (e.g., POST) on a controller route that only has a decorator for a different method (e.g., `@http_get`).","error":"HTTP 405 Method Not Allowed"},{"fix":"Ensure you are using `NinjaExtraAPI()` and call `api.register_controllers(YourControllerClass)`. Note the plural `controllers`.","cause":"Misspelling the method to register controllers or attempting to register a controller with a standard `NinjaAPI` instance.","error":"AttributeError: 'NinjaExtraAPI' object has no attribute 'register_controller'"},{"fix":"Review the API endpoint's expected schema and ensure the incoming request data matches the types, required fields, and constraints defined in your Pydantic model. Check for missing required fields or incorrect data types.","cause":"Input data for a request body or query parameters does not conform to the Pydantic schema defined for the endpoint.","error":"pydantic.error_wrappers.ValidationError: 1 validation error for YourSchema"},{"fix":"Always refer to the official documentation for current import paths. Many core components are directly available from `ninja_extra` (e.g., `from ninja_extra import api_controller`) rather than deeper submodules like `ninja_extra.controllers`.","cause":"Attempting to import a symbol from an incorrect or deprecated path within `django-ninja-extra`.","error":"ModuleNotFoundError: No module named 'ninja_extra.controllers'"}]}