Django Extension
Quick Start
Add anydi.ext.django to the bottom of your INSTALLED_APPS setting in your Django settings file:
INSTALLED_APPS = [
...
"anydi.ext.django",
]
Add AnyDI settings to your Django settings file:
ANYDI = {
"INJECT_URLCONF": "path.to.your.urls",
}
This configuration will inject dependencies into your Django views located in the specified URL configuration (URLconf).
Assume you have a service class that you want to inject into your views:
class HelloService:
def get_message(self) -> str:
return "Hello, World!"
You can now use this service in your views as follows:
import anydi
from django.http import HttpRequest, HttpResponse
def hello(request, hello_service: HelloService = anydi.auto) -> HttpResponse:
return HttpResponse(hello_service.get_message())
In your urls.py, set up the routing:
from django.urls import path
from .views import hello
urlpatterns = [
path("hello", hello),
]
The HelloService will be automatically injected into the hello view through the provided marker anydi.auto.
Settings
ANYDI supports the following settings:
CONTAINER_FACTORY: str | None- Specifies the factory function used to create the container. If not provided, the default container factory will be utilized.REGISTER_SETTINGS: bool- IfTrue, the container will register the Django settings within it.REGISTER_COMPONENTS: bool- IfTrue, the container will register Django components such as the database and cache.INJECT_URLCONF: str | Sequence[str] | None- Specifies the URL configuration where dependencies should be injected.MODULES: Sequence[str]- Lists the modules to be scanned for dependencies.SCAN_PACKAGES: Sequence[str]- Designates the packages to be scanned for dependencies.PATCH_NINJA: bool- IfTrue, the container will modify theninjaframework to support dependency injection.
Django Ninja
If you are using the Django Ninja framework, you can enable dependency injection by setting the PATCH_NINJA to True.
ANYDI = {
"PATCH_NINJA": True,
}
This setting will modify the Django Ninja framework to support dependency injection.
from typing import Any
import anydi
from django.http import HttpRequest
from ninja import Router
from your_module import HelloService
router = Router()
@router.get("/hello")
def hello(request: HttpRequest, hello_service: HelloService = anydi.auto) -> dict[str, Any]:
return {
"message": hello_service.get_message(),
}
The HelloService will be automatically injected into the hello endpoint using the provided marker anydi.auto.
Modules
To add modules to the container, you can use the MODULES setting:
ANYDI = {
"MODULES": [
"yourproject.user.UserModule",
"yourproject.payment.PaymentModule",
],
}
Assume you have a module that provides a UserService class:
from anydi import provider
from yourproject.user.service import UserService
class UserModule:
@provider(scope="singleton")
def user_service(self) -> UserService:
return UserService()
You can now use the UserService in your views as demonstrated in the Quick Start section.
Custom Container
To use a custom container, you can specify the CONTAINER_FACTORY setting:
ANYDI = {
"CONTAINER_FACTORY": "yourproject.config.container.get_container",
}
In yourproject/config/container.py:
from anydi import Container
def get_container() -> Container:
container = Container()
# Add custom container configuration here
return container
Request Scope
To use request-scoped dependencies in your Django application with AnyDI, include the request_scoped_middleware.
This middleware creates request-specific dependency instances at the start of each request, which remain available for the request’s duration.
Add the middleware to your settings.py:
MIDDLEWARE = [
"anydi.ext.django.middleware.request_scoped_middleware",
...
]
With this setup, you can define and utilize request-scoped dependencies throughout your application.
Additionally, HttpRequest dependencies are automatically available in request-scoped providers,
allowing convenient access to the request object and its data in these dependencies.