Detailed examination of ModelViewSet and its role in Django Ninja CRUD viewsets

ModelViewSet

class ModelViewSet()

A viewset offering CRUD operations for a Django model.

Subclasses should specify the Django model via the model class attribute. You
can then attach various views (subclasses of AbstractModelView) to the subclass to
define the CRUD behavior.

Attributes:

  • model Type[Model] - The Django model class for CRUD operations.
  • default_input_schema Optional[Type[Schema]], optional - The default schema to use for
    deserializing the request payload. Defaults to None.
  • default_output_schema Optional[Type[Schema]], optional - The default schema to use for
    serializing the response payload. Defaults to None.

Example:

  1. Define your ModelViewSet and register its routes:
# examples/views/department_views.py
from django.http import HttpRequest
from ninja import Router
from ninja_crud import views, viewsets

from examples.models import Department
from examples.schemas import DepartmentIn, DepartmentOut

router = Router()

class DepartmentViewSet(viewsets.ModelViewSet):
    model = Department

    list_view = views.ListModelView(output_schema=DepartmentOut)
    create_view = views.CreateModelView(input_schema=DepartmentIn, output_schema=DepartmentOut)
    retrieve_view = views.RetrieveModelView(output_schema=DepartmentOut)
    update_view = views.UpdateModelView(input_schema=DepartmentIn, output_schema=DepartmentOut)
    delete_view = views.DeleteModelView()

# The register_routes method must be called to register the routes
DepartmentViewSet.register_routes(router)

# Beyond the CRUD operations managed by the viewset,
# the router can be used in the standard Django Ninja way
@router.get("/statistics/", response=dict)
def retrieve_department_statistics(request: HttpRequest):
    return {"total": Department.objects.count()}
  1. Include your router in your Ninja API configuration:
# config/api.py
from ninja import NinjaAPI
from examples.views.department_views import router as department_router

api = NinjaAPI(...)
api.add_router("departments", department_router)

Notes:

The register_routes method must be called to register the CRUD endpoints
with a Ninja router. This should be done after defining the viewset.

__init_subclass__

def __init_subclass__(cls, **kwargs)

Special method in Python that is automatically called when a class is subclassed.

For ModelViewSet subclasses, this method validates the class attributes and binds
the views to the subclass. It should not be called directly.

register_routes

@classmethod
def register_routes(cls, router: Router) -> None

Register the routes with the given Ninja Router.

This method should be called after all the views have been attached to the
ModelViewSet subclass.

Arguments:

  • router Router - The Ninja Router to register the routes with.