Django JSONField with Pydantic models as a Schema
Project description
Django + Pydantic = 🖤
Django JSONField with Pydantic models as a Schema
Usage
Install the package with pip install django-pydantic-field
.
import pydantic
from django.db import models
from django_pydantic_field import PydanticSchemaField
class Foo(pydantic.BaseModel):
count: int
size: float = 1.0
class Bar(pydantic.BaseModel):
slug: str = "foo_bar"
class MyModel(models.Model):
foo_field = PydanticSchemaField(schema=Foo)
bar_list = PydanticSchemaField(schema=list[Bar])
...
model = MyModel(foo_field={"count": "5"}, bar_list=[{}])
model.save()
assert model.foo_field == Foo(count=5, size=1.0)
assert model.bar_list == [Bar(slug="foo_bar")]
Django REST Framework support
from rest_framework import serializers
from django_pydantic_field.rest_framework import PydanticSchemaField
class MyModelSerializer(serializers.ModelSerializer):
foo_field = PydanticSchemaField(schema=Foo)
class Meta:
model = MyModel
fields = '__all__'
Global approach with typed parser
and renderer
classes
from rest_framework import views
from rest_framework.decorators import api_view, parser_classes, renderer_classes
from django_pydantic_field.rest_framework import PydanticSchemaRenderer, PydanticSchemaParser
@api_view(["POST"])
@parser_classes([PydanticSchemaParser[Foo]]):
@renderer_classes([PydanticSchemaRenderer[list[Foo]]])
def foo_view(request):
assert isinstance(request.data, Foo)
count = request.data.count + 1
return Response([Foo(count=count)])
class FooClassBasedView(views.APIView):
parser_classes = [PydanticSchemaParser[Foo]]
renderer_classes = [PydanticSchemaRenderer[list[Foo]]]
def get(self, request, *args, **kwargs):
assert isinstance(request.data, Foo)
return Response([request.data])
def put(self, request, *args, **kwargs):
assert isinstance(request.data, Foo)
count = request.data.count + 1
return Response([request.data])
Caveats
-
Built-in generic annotations introduced in Python 3.9 are expecting to fail during
manage.py makemigrations
step: due to how Django treats field serialization/reconstruction while writing migrations, it is not possible to create a custom serializer to distinguish between types.GenericAlias and a type instance (any class) without pushing a patch directly in Django.A workaround is to use generic collections from
typing
module, even though they're marked as deprecated and will be eventually removed in the future versions of Python.Note, that this restriction applies only for
PydanticSchemaField
. DRF integrations sould work fine though.
Acknowledgement
- Churkin Oleg for his Gist as a source of inspiration;
- Boutique Air Flight Operations platform as a test ground;
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
Hashes for django-pydantic-field-0.0.6.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 27c83f0235246e606c9c6acadfb801ca351b9530eba5bd93430124b342c600a7 |
|
MD5 | cd3f4329424783babdba543836185ff2 |
|
BLAKE2b-256 | 097be431b94f983f77c4a891e34df2fbc0b1c909f5e33a73b3c499596a9beef8 |
Hashes for django_pydantic_field-0.0.6-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3cd535acd421f0c3a42b3a460c263c7c9552694e5f987e26c89d5bfff5547afb |
|
MD5 | 3fcce7c250475a26f691cd9fadfc990b |
|
BLAKE2b-256 | c658c125b322c553e5c214991d412b51506e073d096afaf2b8616277167dabc8 |