Serialization converts an in-memory object into a representation another machine can store or consume. In a web API, the object exposed to a client is usually not the Django model itself: it is a deliberately shaped representation. That boundary lets non-Python and non-Django clients use the data without needing access to the application’s internals. section 11.1.1
REST-style APIs commonly use HTTP methods as CRUD verbs. An endpoint typically queries a database object, optionally acts on it, serializes it, and sends the result as its response. JSON is a practical output format for that response. section 11.1.1 section 11.2
With Django Ninja, serialization is mostly driven by schemas:
- Use Schema to declare a serializable object with Python type hints, including fields not backed by a model. section 11.2.1
- Use ModelSchema to translate a Django ORM model, selecting exactly which model fields participate in the output. section 11.2.1
- Set an endpoint’s response type to the schema; returning a model instance or queryset then produces the declared JSON shape. section 11.2.1
- Add resolver methods to a ModelSchema when an API representation needs computed fields such as a slug or a URL. section 11.2.2
Serialize a promoter list
A PromoterSchema can point to the Promoter model and expose id, full_name, birth, and death. A GET endpoint returns Promoter.objects.all(), while its response=list[PromoterSchema] tells Ninja to serialize every returned model into a JSON list. The database model stays the source; the schema decides what leaves the API. section 11.2.1
Listing 11.7 API endpoint for fetching a Venue object
# RiffMates/bands/api.py
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.text import slugify
from ninja import Router, ModelSchema
from bands.models import Venue
router = Router() #1
class VenueOut(ModelSchema):
slug: str #2
url: str
class Meta:
model = Venue
fields = ["id", "name", "description"] #3
@staticmethod
def resolve_slug(obj): #4
slug = slugify(obj.name) + "-" + str(obj.id)
return slug
@staticmethod
def resolve_url(obj): #5
url = reverse("api-1.0:fetch_venue", args=[obj.id, ])
return url
@router.get("/venue/{venue_id}/",
response=VenueOut,
url_name="fetch_venue") #6
def fetch_venue(request, venue_id):
venue = get_object_or_404(Venue, id=venue_id)
return venue
This endpoint shows a richer serialized Venue: model fields are selected in Meta, while resolver methods add a human-readable slug and a reverse-generated API URL. section 11.2.2























