Skip to main content

🧩 Modular, composable API views for scalable Django Ninja projects, with built-in CRUD.

Project description

Django Ninja CRUD

Tests Coverage PyPI Version PyPI Downloads License MyPy Ruff

Django Ninja CRUD Cover

Django Ninja CRUD introduces modularity to API development with Django Ninja, revolutionizing how APIs are built and maintained at scale while avoiding repetition. It empowers developers to create reusable, composable API views ranging from built-in CRUD (Create, Read, Update, Delete) operations to complex custom endpoints, supporting both sync and async implementations, all with minimal boilerplate code.

🌞 Key Features

  • Modular Views: Easily extend APIView to create reusable components for repeated business logic. Define views by stating intent, with unrestricted function signatures supporting both sync and async implementations.

  • Flexible Built-in CRUD Views: Pre-built, customizable ListView, CreateView, ReadView, UpdateView, and DeleteView views. Use as-is, customize, or use as blueprints for your own implementations. Supports any path parameters, pagination, filtering, decorators, and more.

  • Powerful Viewset Composition: Use views independently or compose them into APIViewSet for grouped, related views sharing attributes. Design versatile APIs supporting multiple instances of the same view type—perfect for API versioning, or alternative representations.

  • Seamless Django Ninja Integration: Enhance your existing Django Ninja project without changing its structure. Gradually adopt declarative views to clean up your codebase and boost development efficiency.

Django Ninja CRUD Code

[!NOTE] As shared in my DjangoCON Europe 2024 talk, Django Ninja CRUD emerged from countless hours of wrestling with repetitive, complex and hard-to-maintain APIs. My vision is to address those common pain points by providing a declarative and modular approach, making API development not just more efficient, but truly intuitive and enjoyable. I hope it revolutionizes your development experience as it has mine.

📝 Requirements

Python versions Django versions Django Ninja versions

⚒️ Installation

pip install django-ninja-crud

For more information, see the installation guide.

✨ How to Use Built-in CRUD Views

Let's walk through a practical example of using Django Ninja CRUD to create a complete API for a university department system. This example will demonstrate how to set up models, schemas, and views with minimal code.

1. Define Your Model

First, we define a simple Department model:

# examples/models.py
from django.db import models

class Department(models.Model):
    title = models.CharField(max_length=255, unique=True)

2. Create Your Schemas

Next, we define schemas for input and output:

# examples/schemas.py
from ninja import Schema

# For creating/updating departments
class DepartmentIn(Schema):
    title: str

# For retrieving department data
class DepartmentOut(Schema):
    id: int
    title: str

3. Set Up Your Views

Now, here's where Django Ninja CRUD shines. Set up all CRUD operations in one concise class:

# examples/views/department_views.py
from typing import List

from ninja import NinjaAPI
from ninja_crud import views, viewsets

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

api = NinjaAPI()

class DepartmentViewSet(viewsets.APIViewSet):
    api = api
    model = Department

    # Define all CRUD operations with minimal code
    list_departments = views.ListView(response_body=List[DepartmentOut])
    create_department = views.CreateView(request_body=DepartmentIn, response_body=DepartmentOut)
    read_department = views.ReadView(response_body=DepartmentOut)
    update_department = views.UpdateView(request_body=DepartmentIn, response_body=DepartmentOut)
    delete_department = views.DeleteView()

# You can still add custom endpoints as needed using pure Django Ninja syntax
@api.get("/stats/")
def get_department_stats(request):
    return {"total": Department.objects.count()}

This code automatically creates the following API endpoints:

  • GET / - List all departments with pagination limit/offset
  • POST / - Create a new department
  • GET /{id} - Retrieve a specific department
  • PUT /{id} - Update a specific department
  • DELETE /{id} - Delete a specific department
  • GET /stats/ - Custom endpoint for department statistics

4. Simplified Version with Defaults

For even more concise code, if your views are straightforward, you can leverage the APIViewSet class to define them with default request and response bodies:

# examples/views/department_views.py
from ninja import NinjaAPI
from ninja_crud import views, viewsets

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

api = NinjaAPI()


class DepartmentViewSet(viewsets.APIViewSet):
    api = api
    model = Department
    default_request_body = DepartmentIn
    default_response_body = DepartmentOut

    # Extremely concise CRUD definitions
    list_departments = views.ListView()
    create_department = views.CreateView()
    read_department = views.ReadView()
    update_department = views.UpdateView()
    delete_department = views.DeleteView()

This produces the same API endpoints as the previous example, but with even less code.

5. Error Handling

[!WARNING] Django Ninja CRUD's provided CRUD endpoints DO NOT include built-in error handling. This design choice allows you to maintain full control over error responses and adhere to your application's specific conventions.

To properly handle exceptions such as ObjectDoesNotExist, validation errors, or any other potential issues, you need to define custom exception handlers as specified in the Django Ninja documentation.

For example, to handle ObjectDoesNotExist exceptions, you might add the following to your code:

from django.core.exceptions import ObjectDoesNotExist
from ninja import NinjaAPI

api = NinjaAPI()

@api.exception_handler(ObjectDoesNotExist)
def handle_object_does_not_exist(request, exc):
    return api.create_response(
        request,
        {"message": "Object not found"},
        status=404,
    )

☔️ Testing

Django Ninja CRUD is designed to work seamlessly with Django's testing framework and other third-party testing tools. Users are encouraged to implement thorough tests for their APIs using their preferred testing methodologies.

[!NOTE] Previously, Django Ninja CRUD included built-in testing utilities. These have been separated into a standalone project, django-rest-testing, to allow for broader use cases beyond Django Ninja. While it offers a declarative, scenario-based approach to API testing, it's still in active development. The project aims to improve its functionality and developer experience over time. Users are advised to evaluate it alongside other testing methods to find the best fit for their projects.

While Django Rest Testing is used in Django Ninja CRUD's own test suite, it is not a runtime dependency. Users are free to choose the testing approach that best suits their needs without any limitations imposed by the main package.

📚 Documentation

For more information, see the documentation.

🌎 International Documentation

[!WARNING] Community-contributed translations may not always reflect the latest updates.

🫶 Support

First and foremost, a heartfelt thank you to the 400+ stargazers who have shown their support for this project!

Star History Chart

As an open-source project, Django Ninja CRUD thrives on community contributions and support. Here are some ways you can help:

  • 🌟 Star the repo
  • 🙌 Share your experience
  • 🐝 Report issues
  • 🔥 Contribute code
  • 💕 Sponsor the project

Your support, in any form, propels this project forward and helps it reach more developers in need of a powerful, intuitive API development framework. Thank you! 🙏

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_ninja_crud-0.6.2.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

django_ninja_crud-0.6.2-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file django_ninja_crud-0.6.2.tar.gz.

File metadata

  • Download URL: django_ninja_crud-0.6.2.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.6 Linux/6.8.0-1014-azure

File hashes

Hashes for django_ninja_crud-0.6.2.tar.gz
Algorithm Hash digest
SHA256 f6698469e19687b646afed1b0aa5a12aec9fbb2192b1c69f97e0219f4644bfed
MD5 09bfc4783126f564266579e2b4dc7629
BLAKE2b-256 0a50bcea64366f7d32ec9df12ba0fa7a41ce8845879ada68dc1fc7cbf8b17b10

See more details on using hashes here.

File details

Details for the file django_ninja_crud-0.6.2-py3-none-any.whl.

File metadata

  • Download URL: django_ninja_crud-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.6 Linux/6.8.0-1014-azure

File hashes

Hashes for django_ninja_crud-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8c769f58143b7359bfd7f90c9abd5a6abe12de9335d7ee8ce19e13e5dc31fd51
MD5 cef17eacf79d015f849913af067975a0
BLAKE2b-256 2900a9f1eb25d616897147669ca5a8e964e9a84e71df3d46269eafb724df6824

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page