{"id":13579499,"url":"https://github.com/hbakri/django-ninja-crud","last_synced_at":"2025-05-14T20:04:35.030Z","repository":{"id":174181614,"uuid":"651888019","full_name":"hbakri/django-ninja-crud","owner":"hbakri","description":"🧩 Modular, composable API views for scalable Django Ninja projects, with built-in CRUD.","archived":false,"fork":false,"pushed_at":"2025-03-25T08:46:47.000Z","size":2448,"stargazers_count":570,"open_issues_count":6,"forks_count":20,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-06T08:11:11.651Z","etag":null,"topics":["api","crud","django","django-ninja","python","rest"],"latest_commit_sha":null,"homepage":"https://django-ninja-crud.readme.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hbakri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"hbakri"}},"created_at":"2023-06-10T11:55:17.000Z","updated_at":"2025-03-29T22:31:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"e66f3e8e-d4c0-4f4f-ac29-28922982ab76","html_url":"https://github.com/hbakri/django-ninja-crud","commit_stats":null,"previous_names":["hbakri/django-ninja-crud"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbakri%2Fdjango-ninja-crud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbakri%2Fdjango-ninja-crud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbakri%2Fdjango-ninja-crud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hbakri%2Fdjango-ninja-crud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hbakri","download_url":"https://codeload.github.com/hbakri/django-ninja-crud/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248710408,"owners_count":21149185,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","crud","django","django-ninja","python","rest"],"created_at":"2024-08-01T15:01:39.993Z","updated_at":"2025-04-13T11:46:43.317Z","avatar_url":"https://github.com/hbakri.png","language":"Python","funding_links":["https://github.com/sponsors/hbakri"],"categories":["Python"],"sub_categories":[],"readme":"# Django Ninja CRUD\n[![Tests](https://github.com/hbakri/django-ninja-crud/actions/workflows/tests.yml/badge.svg)](https://github.com/hbakri/django-ninja-crud/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/hbakri/django-ninja-crud/main.svg?label=coverage\u0026logo=codecov\u0026logoColor=white)](https://codecov.io/gh/hbakri/django-ninja-crud)\n[![PyPI - Version](https://img.shields.io/pypi/v/django-ninja-crud?color=g\u0026logo=pypi\u0026logoColor=white)](https://pypi.org/project/django-ninja-crud/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/django-ninja-crud?logo=esri\u0026logoColor=white)](https://pypistats.org/packages/django-ninja-crud)\n[![PyPI - License](https://img.shields.io/pypi/l/django-ninja-crud)](https://github.com/hbakri/django-ninja-crud/blob/main/LICENSE)\n[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n![Django Ninja CRUD Cover](https://raw.githubusercontent.com/hbakri/django-ninja-crud/main/docs/assets/images/django-ninja-crud-cover.JPG)\n\n**Django Ninja CRUD** introduces [**modularity**](https://en.wikipedia.org/wiki/Modular_programming) to API development with [**Django Ninja**](https://github.com/vitalik/django-ninja), revolutionizing how APIs are built and maintained at scale while avoiding repetition. It empowers developers to create reusable, [**composable**](https://en.wikipedia.org/wiki/Composability) API views ranging from built-in [**CRUD** (**C**reate, **R**ead, **U**pdate, **D**elete)](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations to complex custom endpoints, supporting both sync and async implementations, all with minimal boilerplate code.\n\n## 🌞 Key Features\n- **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.\n\n- **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.\n\n- **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.\n\n- **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.\n\n![Django Ninja CRUD Code](https://raw.githubusercontent.com/hbakri/django-ninja-crud/main/docs/assets/images/django-ninja-crud-code.JPG)\n\n\u003e [!NOTE]\n\u003e As shared in my [DjangoCON Europe 2024 talk](https://www.youtube.com/watch?v=r8yRxZPcy9k\u0026t=1168s),\n\u003e Django Ninja CRUD emerged from countless hours of wrestling with repetitive, complex\n\u003e and hard-to-maintain APIs. My vision is to address those common pain points by\n\u003e providing a declarative and modular approach, making API development not just more\n\u003e efficient, but truly intuitive and enjoyable. I hope it revolutionizes your\n\u003e development experience as it has mine.\n\n## 📝 Requirements\n\n[![Python versions](https://img.shields.io/pypi/pyversions/django-ninja-crud.svg?color=306998\u0026label=python\u0026logo=python\u0026logoColor=white)](https://github.com/python/cpython)\n[![Django versions](https://img.shields.io/badge/4.2_%7C_5.0_%7C_5.1-blue?color=0C4B33\u0026label=django\u0026logo=django\u0026logoColor=white)](https://github.com/django/django)\n[![Django Ninja versions](https://img.shields.io/badge/1.0_%7C_1.1_%7C_1.2_%7C_1.3-blue?color=black\u0026label=django-ninja\u0026logo=fastapi\u0026logoColor=white)](https://github.com/vitalik/django-ninja)\n\n## ⚒️ Installation\n```bash\npip install django-ninja-crud\n```\nFor more information, see the [installation guide](https://django-ninja-crud.readme.io/docs/02-installation).\n\n## ✨ How to Use Built-in CRUD Views\n\nLet'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.\n\n### 1. Define Your Model\n\nFirst, we define a simple `Department` model:\n```python\n# examples/models.py\nfrom django.db import models\n\nclass Department(models.Model):\n    title = models.CharField(max_length=255, unique=True)\n```\n\n### 2. Create Your Schemas\n\nNext, we define schemas for input and output:\n```python\n# examples/schemas.py\nfrom ninja import Schema\n\n# For creating/updating departments\nclass DepartmentIn(Schema):\n    title: str\n\n# For retrieving department data\nclass DepartmentOut(Schema):\n    id: int\n    title: str\n```\n\n### 3. Set Up Your Views\nNow, here's where Django Ninja CRUD shines. Set up all CRUD operations in one concise class:\n\n```python\n# examples/views/department_views.py\nfrom typing import List\n\nfrom ninja import NinjaAPI\nfrom ninja_crud import views, viewsets\n\nfrom examples.models import Department\nfrom examples.schemas import DepartmentIn, DepartmentOut\n\napi = NinjaAPI()\n\nclass DepartmentViewSet(viewsets.APIViewSet):\n    api = api\n    model = Department\n\n    # Define all CRUD operations with minimal code\n    list_departments = views.ListView(response_body=List[DepartmentOut])\n    create_department = views.CreateView(request_body=DepartmentIn, response_body=DepartmentOut)\n    read_department = views.ReadView(response_body=DepartmentOut)\n    update_department = views.UpdateView(request_body=DepartmentIn, response_body=DepartmentOut)\n    delete_department = views.DeleteView()\n\n# You can still add custom endpoints as needed using pure Django Ninja syntax\n@api.get(\"/stats/\")\ndef get_department_stats(request):\n    return {\"total\": Department.objects.count()}\n```\n\nThis code automatically creates the following API endpoints:\n- GET `/` - List all departments with pagination limit/offset\n- POST `/` - Create a new department\n- GET `/{id}` - Retrieve a specific department\n- PUT `/{id}` - Update a specific department\n- DELETE `/{id}` - Delete a specific department\n- GET `/stats/` - Custom endpoint for department statistics\n\n### 4. Simplified Version with Defaults\n\nFor even more concise code, if your views are straightforward, you can leverage the\n`APIViewSet` class to define them with default request and response bodies:\n```python\n# examples/views/department_views.py\nfrom ninja import NinjaAPI\nfrom ninja_crud import views, viewsets\n\nfrom examples.models import Department\nfrom examples.schemas import DepartmentIn, DepartmentOut\n\napi = NinjaAPI()\n\n\nclass DepartmentViewSet(viewsets.APIViewSet):\n    api = api\n    model = Department\n    default_request_body = DepartmentIn\n    default_response_body = DepartmentOut\n\n    # Extremely concise CRUD definitions\n    list_departments = views.ListView()\n    create_department = views.CreateView()\n    read_department = views.ReadView()\n    update_department = views.UpdateView()\n    delete_department = views.DeleteView()\n```\n\nThis produces the same API endpoints as the previous example, but with even less code.\n\n### 5. Error Handling\n\n\u003e [!WARNING]\n\u003e Django Ninja CRUD's provided CRUD endpoints **DO NOT** include built-in error handling.\n\u003e This design choice allows you to maintain full control over error responses and\n\u003e adhere to your application's specific conventions.\n\nTo properly handle exceptions such as `ObjectDoesNotExist`, validation errors, or any\nother potential issues, you need to define custom exception handlers as specified in\nthe [Django Ninja documentation](https://django-ninja.dev/guides/errors/).\n\nFor example, to handle `ObjectDoesNotExist` exceptions, you might add the following to\nyour code:\n```python\nfrom django.core.exceptions import ObjectDoesNotExist\nfrom ninja import NinjaAPI\n\napi = NinjaAPI()\n\n@api.exception_handler(ObjectDoesNotExist)\ndef handle_object_does_not_exist(request, exc):\n    return api.create_response(\n        request,\n        {\"message\": \"Object not found\"},\n        status=404,\n    )\n```\n\n## ☔️ Testing\n\nDjango Ninja CRUD is designed to work seamlessly with Django's testing framework and\nother third-party testing tools. Users are encouraged to implement thorough tests for\ntheir APIs using their preferred testing methodologies.\n\n\u003e [!NOTE]\n\u003e Previously, Django Ninja CRUD included built-in testing utilities. These have been\n\u003e separated into a standalone project, [django-rest-testing](https://github.com/hbakri/django-rest-testing),\n\u003e to allow for broader use cases beyond Django Ninja. While it offers a declarative,\n\u003e scenario-based approach to API testing, it's still in active development. The project\n\u003e aims to improve its functionality and developer experience over time. Users are\n\u003e advised to evaluate it alongside other testing methods to find the best fit for\n\u003e their projects.\n\nWhile **Django Rest Testing** is used in Django Ninja CRUD's own test suite, it is not a\nruntime dependency. Users are free to choose the testing approach that best suits their\nneeds without any limitations imposed by the main package.\n\n## 📚 Documentation\nFor more information, see the [documentation](https://django-ninja-crud.readme.io/).\n\n## 🌎 International Documentation\n\n- [Chinese Documentation](https://django-ninja.cn/django-ninja-crud/) (Community Contributed)\n\n\u003e [!WARNING]\n\u003e Community-contributed translations may not always reflect the latest updates.\n\n## 🫶 Support\nFirst and foremost, a heartfelt thank you to the 400+ stargazers who have shown their\nsupport for this project!\n\n[![Star History Chart](https://api.star-history.com/svg?repos=hbakri/django-ninja-crud\u0026type=Date)](https://star-history.com/#hbakri/django-ninja-crud\u0026Date)\n\nAs an open-source project, Django Ninja CRUD thrives on community contributions and\nsupport. Here are some ways you can help:\n\n- 🌟 Star the repo\n- 🙌 Share your experience\n- 🐝 Report issues\n- 🔥 Contribute code\n- 💕 [Sponsor the project](https://github.com/sponsors/hbakri)\n\nYour support, in any form, propels this project forward and helps it reach more\ndevelopers in need of a powerful, intuitive API development framework. Thank you! 🙏\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhbakri%2Fdjango-ninja-crud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhbakri%2Fdjango-ninja-crud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhbakri%2Fdjango-ninja-crud/lists"}