Django Ninja AIO CRUD - Rest Framework
Project description
🥷 django-ninja-aio-crud
[!NOTE] Django ninja aio crud framework is based on Django Ninja framework. It comes out with built-in views and models which are able to make automatic async CRUD operations and codes views class based making the developers' life easier and the code cleaner.
📝 Instructions
📚 Prerequisites
- Install Python from the official website (latest version) and ensure it is added to the system Path and environment variables.
💻 Setup your environment
- Create a virtual environment
python -m venv .venv
✅ Activate it
- If you are from linux activate it with
. .venv/bin/activate
- If you are from windows activate it with
. .venv/Scripts/activate
📥 Install package
pip install django-ninja-aio-crud
🚀 Usage
[!TIP] If you find django ninja aio crud useful, consider :star: this project and why not ... Buy me a coffee
ModelSerializer
- You can serialize your models using ModelSerializer and made them inherit from it. In your models.py import ModelSerializer
# models.py
from django.db import models
from ninja_aio.models import ModelSerializer
class Foo(ModelSerializer):
name = models.CharField(max_length=30)
bar = models.CharField(max_length=30)
class ReadSerializer:
fields = ["id", "name", "bar"]
class CreateSerializer:
fields = ["name", "bar"]
class UpdateSerializer:
fields = ["name", "bar"]
- ReadSerializer, CreateSerializer, UpdateSerializer are used to define which fields would be included in runtime schemas creation. You can also specify custom fields and handle their function by overriding custom_actions ModelSerializer's method(custom fields are only available for Create and Update serializers).
# models.py
from django.db import models
from ninja_aio.models import ModelSerializer
class Foo(ModelSerializer):
name = models.CharField(max_length=30)
bar = models.CharField(max_length=30)
active = models.BooleanField(default=False)
class ReadSerializer:
fields = ["id", "name", "bar"]
class CreateSerializer:
customs = [("force_activation", bool, False)]
fields = ["name", "bar"]
class UpdateSerializer:
fields = ["name", "bar"]
async def custom_actions(self, payload: dict[str, Any]):
if not payload.get("force_activation"):
return
setattr(self, "force_activation", True)
async def post_create(self) -> None:
if not hasattr(self, "force_activation") or not getattr(self, "force_activation"):
return
self.active = True
await self.asave()
- post create method is a custom method that comes out to handle actions which will be excuted after that the object is created. It can be used, indeed, for example to handle custom fields' actions.
APIViewSet
- View class used to automatically generate CRUD views. in your views.py import APIViewSet and define your api using NinjaAIO class. NinjaAIO class uses built-in parser and renderer which use orjson for data serialization.
# views.py
from ninja_aio import NinjaAIO
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAIO()
class FooAPI(APIViewSet):
model = Foo
api = api
FooAPI().add_views_to_route()
- and that's it, your model CRUD will be automatically created. You can also add custom views to CRUD overriding the built-in method "views".
# views.py
from ninja import Schema
from ninja_aio import NinjaAIO
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAIO()
class ExampleSchemaOut(Schema):
sum: float
class ExampleSchemaIn(Schema):
n1: float
n2: float
class FooAPI(APIViewSet):
model = Foo
api = api
def views(self):
@self.router.post("numbers-sum/", response={200: ExampleSchemaOut})
async def sum(request: HttpRequest, data: ExampleSchemaIn):
return 200, {sum: data.n1 + data.n2}
FooAPI().add_views_to_route()
APIView
- View class to code generic views class based. In your views.py import APIView class.
# views.py
from ninja import Schema
from ninja_aio import NinjaAIO
from ninja_aio.views import APIView
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
api = NinjaAIO()
class ExampleSchemaOut(Schema):
sum: float
class ExampleSchemaIn(Schema):
n1: float
n2: float
class SumView(APIView):
api = api
api_router_path = "numbers-sum/"
router_tag = "Sum"
def views(self):
@self.router.post("/", response={200: ExampleSchemaOut})
async def sum(request: HttpRequest, data: ExampleSchemaIn):
return 200, {sum: data.n1 + data.n2}
SumView().add_views_to_route()
Relations
-
You can also set ForeignKey, OneToOne and ManyToMany relations into serialization(reverse relations are supported too). Django ninja aio crud will serialize every of these relation automatically.
-
Define models:
# models.py
class Bar(ModelSerializer):
name = models.CharField(max_length=30)
description = models.TextField(max_length=30)
# ReadSerializer with reverse OneToMany relation (foos)
class ReadSerializer:
fields = ["id", "name", "description", "foos"]
class CreateSerializer:
fields = ["name", "description"]
class UpdateSerializer:
fields = ["name", "description"]
class Foo(ModelSerializer):
name = models.CharField(max_length=30)
bar = models.ForeignKey(Bar, on_delete=models.CASCADE, related_name="foos")
class ReadSerializer:
fields = ["id", "name", "bar"]
class CreateSerializer:
fields = ["name", "bar"]
class UpdateSerializer:
fields = ["name"]
- Define views:
# views.py
from ninja_aio import NinjaAIO
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo, Bar
api = NinjaAIO()
class FooAPI(APIViewSet):
model = Foo
api = api
class BarAPI(APIViewSet):
model = Bar
api = api
FooAPI().add_views_to_route()
BarAPI().add_views_to_route()
- Now run your server and go to /docs url:
Docs
- Foo Schemas
- Bar Schemas with reverse relation
🔒 Authentication
Jwt
- AsyncJWTBearer built-in class is an authenticator class which use joserfc module. It cames out with authenticate method which validate given claims. Override auth handler method to write your own authentication method. Default algorithms used is RS256. a jwt Token istance is set as class atribute so you can use it by self.dcd.
from ninja_aio.auth import AsyncJWTBearer
from django.conf import settings
from django.http import HttpRequest
from .models import Foo
class CustomJWTBearer(AsyncJWTBearer):
jwt_public = settings.JWT_PUBLIC
claims = {"foo_id": {"essential": True}}
async def auth_handler(self, request: HttpRequest):
try:
request.user = await Foo.objects.aget(id=self.dcd.claims["foo_id"])
except Foo.DoesNotExist:
return None
return request.user
- Then add it to views.
# views.py
from ninja import Schema
from ninja_aio import NinjaAIO
from ninja_aio.views import APIViewSet, APIView
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAIO()
class FooAPI(APIViewSet):
model = Foo
api = api
auths = CustomJWTBearer()
class ExampleSchemaOut(Schema):
sum: float
class ExampleSchemaIn(Schema):
n1: float
n2: float
class SumView(APIView):
api = api
api_router_path = "numbers-sum/"
router_tag = "Sum"
auths = CustomJWTBearer()
def views(self):
@self.router.post("/", response={200: ExampleSchemaOut}, auth=self.auths)
async def sum(request: HttpRequest, data: ExampleSchemaIn):
return 200, {sum: data.n1 + data.n2}
FooAPI().add_views_to_route()
SumView().add_views_to_route()
📝 Pagination
- By default APIViewSet list view uses Django Ninja built-in AsyncPagination class "PageNumberPagination". You can customize and assign it to APIViewSet class. To make your custom pagination consult Django Ninja pagination documentation.
# views.py
class FooAPI(APIViewSet):
model = Foo
api = api
pagination_class = CustomPaginationClass
📌 Notes
- Feel free to contribute and improve the program. 🛠️
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Close
Hashes for django_ninja_aio_crud-0.3.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0af9ba326f298fc0776f512a3d654d5749c983accfedb99059e40e22e55761fe |
|
MD5 | 8436888b83453410c4531b0b79108620 |
|
BLAKE2b-256 | a732d2480943b9f1d58503e8d2e2fc5c93ead4e36cbccd669f48a86ae65fa333 |
Close
Hashes for django_ninja_aio_crud-0.3.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8c0d51a12b9c5510ec60a1a1730cc16eeea6d30af662f79c2b55b38850e8639e |
|
MD5 | 552098d5427e7dd38f0f47bcac87bb1e |
|
BLAKE2b-256 | deffb99db3644407c8b23e0f3b2c02fc5e8ea67d56e5eff4498b6bf235ffc5b7 |