Django Ninja Extra is a powerful extension for Django Ninja that enhances your Django REST API development experience. It introduces class-based views and advanced features while maintaining the high performance and simplicity of Django Ninja. Whether you're building a small API or a large-scale application, Django Ninja Extra provides the tools you need for clean, maintainable, and efficient API development.
- ⚡ High Performance: Built on Pydantic for lightning-fast validation
- 🔄 Async Support: First-class support for async/await operations
- 📝 Type Safety: Comprehensive type hints for better development experience
- 🎯 Django Integration: Seamless integration with Django's ecosystem
- 📚 OpenAPI Support: Automatic API documentation with Swagger/ReDoc
-
🏗️ Class-Based Controllers:
- Organize related endpoints in controller classes
- Inherit common functionality
- Share dependencies across endpoints
-
🔒 Advanced Permission System (Similar to Django Rest Framework):
- Controller-level permissions
- Route-level permission overrides
- Custom permission classes
-
💉 Dependency Injection:
- Built-in support for Injector
- Compatible with django_injector
- Automatic dependency resolution
-
🔧 Service Layer:
- Injectable services for business logic
- Better separation of concerns
- Reusable components
- Python >= 3.6
- Django >= 2.1
- Pydantic >= 1.6
- Django-Ninja >= 0.16.1
- Install the package:
pip install django-ninja-extra
- Add to INSTALLED_APPS:
INSTALLED_APPS = [
...,
'ninja_extra',
]
Create api.py
in your Django project:
from ninja_extra import NinjaExtraAPI, api_controller, http_get
api = NinjaExtraAPI()
# Function-based endpoint example
@api.get("/hello", tags=['Basic'])
def hello(request, name: str = "World"):
return {"message": f"Hello, {name}!"}
# Class-based controller example
@api_controller('/math', tags=['Math'])
class MathController:
@http_get('/add')
def add(self, a: int, b: int):
"""Add two numbers"""
return {"result": a + b}
@http_get('/multiply')
def multiply(self, a: int, b: int):
"""Multiply two numbers"""
return {"result": a * b}
# Register your controllers
api.register_controllers(MathController)
In urls.py
:
from django.urls import path
from .api import api
urlpatterns = [
path("api/", api.urls), # This will mount your API at /api/
]
from ninja_extra import api_controller, http_get
from ninja_extra.permissions import IsAuthenticated, PermissionBase
# Custom permission
class IsAdmin(PermissionBase):
def has_permission(self, context):
return context.request.user.is_staff
@api_controller('/admin', tags=['Admin'], permissions=[IsAuthenticated, IsAdmin])
class AdminController:
@http_get('/stats')
def get_stats(self):
return {"status": "admin only data"}
@http_get('/public', permissions=[]) # Override to make public
def public_stats(self):
return {"status": "public data"}
from injector import inject
from ninja_extra import api_controller, http_get
# Service class
class UserService:
def get_user_details(self, user_id: int):
return {"user_id": user_id, "status": "active"}
# Controller with dependency injection
@api_controller('/users', tags=['Users'])
class UserController:
def __init__(self, user_service: UserService):
self.user_service = user_service
@http_get('/{user_id}')
def get_user(self, user_id: int):
return self.user_service.get_user_details(user_id)
Access your API's interactive documentation at /api/docs
:
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch
- Write your changes
- Submit a pull request
Please ensure your code follows our coding standards and includes appropriate tests.
This project is licensed under the MIT License - see the LICENSE file for details.
- ⭐ Star the repository
- 🐛 Report issues
- 📖 Contribute to documentation
- 🤝 Submit pull requests