Expose your models as a JSON API with Django REST Framework — serializers, API views, ViewSets, and routers — plus where Django Ninja fits in.
Why: DRF is the standard toolkit for building JSON APIs on top of Django models. Note: install it and add "rest_framework" to INSTALLED_APPS — then your models can speak JSON.
pip install djangorestframeworkThen add it to INSTALLED_APPS in config/settings.py:
INSTALLED_APPS += ["rest_framework"]Why: a serializer is the API’s version of a form — it converts model instances to JSON and validates incoming JSON back into models. When ModelSerializer: it reads your model and builds the fields, just like ModelForm. Where: blog/serializers.py.
# blog/serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
author = serializers.StringRelatedField(read_only=True)
class Meta:
model = Post
fields = ["id", "title", "slug", "body", "status", "author"]Why: @api_view turns a normal function into a DRF endpoint that handles JSON, content negotiation, and the browsable API. Note: Response serializes Python data to JSON automatically; request.data is the parsed request body.
# blog/api.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Post
from .serializers import PostSerializer
@api_view(["GET", "POST"])
def post_list_api(request):
if request.method == "POST":
serializer = PostSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=201)
posts = Post.objects.all()
return Response(PostSerializer(posts, many=True).data)Why: a ModelViewSet gives you list, retrieve, create, update, and delete in a handful of lines, and a router generates all the URLs for them. When: standard CRUD APIs — which is most of them. Note: this replaces writing each endpoint by hand.
# blog/api.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# config/urls.py
from rest_framework.routers import DefaultRouter
from blog.api import PostViewSet
router = DefaultRouter()
router.register("posts", PostViewSet) # → /posts/ and /posts/{id}/
urlpatterns += [path("api/", include(router.urls))]When Django Ninja: you prefer FastAPI-style code — Python type hints for validation and automatic OpenAPI docs — instead of DRF’s class-based style. Note: it is a lighter, newer alternative; DRF is still the most widely used. Pick one, not both.
# pip install django-ninja
from ninja import NinjaAPI, ModelSchema
from .models import Post
api = NinjaAPI()
class PostSchema(ModelSchema):
class Meta:
model = Post
fields = ["id", "title", "slug", "body"]
@api.get("/posts", response=list[PostSchema])
def list_posts(request):
return Post.objects.all()