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 NinjaAPI class. As Parser and Render of the API you must use ninja_aio built-in classes which will serialize data using orjson.
# views.py
from ninja import NinjAPI
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAPI(renderer=ORJSONRenderer(), parser=ORJSONParser())
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 NinjAPI, Schema
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAPI(renderer=ORJSONRenderer(), parser=ORJSONParser())
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 NinjAPI, Schema
from ninja_aio.views import APIView
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
api = NinjaAPI(renderer=ORJSONRenderer(), parser=ORJSONParser())
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 and OneToOne relations into serialization(reverse relations are supported too). Django ninja aio crud will serialize every of these relation automatically.
[!WARNING] Only ForeignKey and OneToOne relations are supported for serialization, ManyToMany relations are not supported yet.
- 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 import NinjAPI
from ninja_aio.views import APIViewSet
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo, Bar
api = NinjaAPI(renderer=ORJSONRenderer(), parser=ORJSONParser())
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 NinjAPI, Schema
from ninja_aio.views import APIViewSet, APIView
from ninja_aio.parsers import ORJSONParser
from ninja_aio.renders import ORJSONRender
from .models import Foo
api = NinjaAPI(renderer=ORJSONRenderer(), parser=ORJSONParser())
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.1.4.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5e80f5d2a627c155c1c8af687ecc63658af9ed1e2e6a2306d91b063ec5146880 |
|
MD5 | ae5e3309c458e5f7bc879868dceb29db |
|
BLAKE2b-256 | c9451b1fba87b05deafd45ddee19029c6eb567f69c5ce39cd720226bce1507d4 |
Close
Hashes for django_ninja_aio_crud-0.1.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3876ed13122dde4bbf0cd24d266740e875288f50d3739d8a29406102cd0f8bce |
|
MD5 | 1f8a44e9174e2767f069fe63436af2aa |
|
BLAKE2b-256 | 5608e3bc6278ec017181215ae2e5cd64792fa8ea8e9633a32f660c656534a31d |