Privacy Policy
Snippets index

  django-ninja Notes

Hello world

from ninja import Router
v1_router = Router(tags=["cclib"])


@v1_router.get("/hello")
def hello(request):
    return "Hello world!"

A basic example to expose a Django Model

from typing import List
import uuid
from django.shortcuts import get_object_or_404
from ninja import Router
from ninja import Schema, ModelSchema
from ninja.security import django_auth

from cclib.resources.models import Document

v1_router = Router(tags=["cclib"])


class DocumentSchema(ModelSchema):
    class Meta:
        model = Document
        fields = "__all__"


@v1_router.get("/documents/{uuid:document_id}", response=DocumentSchema, auth=django_auth)
def get_document(request, document_id: uuid.UUID):
    return get_object_or_404(Document, pk=document_id)


@v1_router.get("/documents", response=List[DocumentSchema], auth=django_auth)
def list_documents(request):
    qs = Document.objects.all()
    return qs

Nested objects

There is also often a need to return responses with some nested/child objects ...

https://django-ninja.dev/guides/response/#nested-objects

See also:

Django Ninja nested Schemas

Example:

import traceback
from typing import List
from ninja import Router
from ninja import Schema, ModelSchema
from ninja.errors import HttpError
from ninja.security import django_auth
from ninja.security import django_auth_superuser
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth import get_user_model

v1_router = Router(tags=["ccserver"])


class GroupSchema(ModelSchema):
    class Meta:
        model = Group
        fields = "__all__"

class UserSchema(ModelSchema):
    # See: "Nested objects"
    # https://django-ninja.dev/guides/response/#nested-objects
    groups: List[GroupSchema] = []
    class Meta:
        model = get_user_model()
        #fields = "__all__"
        fields = [
            'id',
            'username',
        ]


@v1_router.get("/users", response=List[UserSchema], auth=django_auth_superuser)
def list_users(request):
    try:
        User = get_user_model()
        qs = User.objects.all()
    except Exception as e:
        # See: "Throwing HTTP responses with exceptions"
        # https://django-ninja.dev/guides/errors/#throwing-http-responses-with-exceptions
        raise HttpError(500, str(e) + "\n" + traceback.format_exc())

    return qs

Aliases

Instead of a nested response, you may want to just flatten the response output.

The Ninja Schema object extends Pydantic's Field(..., alias="") format to work with dotted responses.

See: https://django-ninja.dev/guides/response/#aliases

Authentication

https://django-ninja.dev/guides/authentication/

Examples:

from ninja import NinjaAPI
from ninja.security import django_auth

api = NinjaAPI(csrf=True)

@api.get("/pets", auth=django_auth)
def pets(request):
    return f"Authenticated user {request.auth}"

If you need to authorize only a superuser, you can use from ninja.security import django_auth_superuser instead.

Here's an example where the client, in order to authenticate, needs to pass a header:

Authorization: Bearer supersecret:

from ninja.security import HttpBearer


class AuthBearer(HttpBearer):
    def authenticate(self, request, token):
        if token == "supersecret":
            return token


@api.get("/bearer", auth=AuthBearer())
def bearer(request):
    return {"token": request.auth}

Throwing HTTP responses with exceptions

As an alternative to custom exceptions and writing handlers for it - you can as well throw http exception that will lead to returning a http response with desired code

https://django-ninja.dev/guides/errors/#throwing-http-responses-with-exceptions

from ninja.errors import HttpError

@api.get("/some/resource")
def some_operation(request):
    if True:
        raise HttpError(503, "Service Unavailable. Please retry later.")

Best practices

Have separate routers for each domain:

https://django-ninja.dev/guides/routers/

See also the following discussion:

https://www.reddit.com/r/django/comments/13zg8uw/django_ninja_architecture/