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 datetime import date
from uuid import UUID
from django.db import models
from django_pydantic_field import SchemaField
class Foo(pydantic.BaseModel):
count: int
size: float = 1.0
class Bar(pydantic.BaseModel):
slug: str = "foo_bar"
class MyModel(models.Model):
# Infer schema from field annotation
foo_field: Foo = SchemaField()
# or explicitly pass schema to the field
bar_list: typing.Sequence[Bar] = SchemaField(schema=list[Bar])
# Pydantic exportable types are supported
raw_date_map: dict[int, date] = SchemaField()
raw_uids: set[UUID] = SchemaField()
...
model = MyModel(
foo_field={"count": "5"},
bar_list=[{}],
raw_date_map={1: "1970-01-01"},
raw_uids={"17a25db0-27a4-11ed-904a-5ffb17f92734"}
)
model.save()
assert model.foo_field == Foo(count=5, size=1.0)
assert model.bar_list == [Bar(slug="foo_bar")]
assert model.raw_date_map = {1: date(1970, 1, 1)}
assert model.raw_uids = {UUID("17a25db0-27a4-11ed-904a-5ffb17f92734")}
Practically, schema could be of any type supported by Pydantic.
In addition, an external config
class can be passed for such schemes.
Limitation: Forward referencing annotations
Note, at the moment it is not possible to use string annotations and forward references. I tried to defer schema initialzation at a field descriptor level, but this approach did not succeeded with current migrations flow.
Django REST Framework support
from rest_framework import generics, serializers
from django_pydantic_field.rest_framework import SchemaField, AutoSchema
class MyModelSerializer(serializers.ModelSerializer):
foo_field = SchemaField(schema=Foo)
class Meta:
model = MyModel
fields = '__all__'
class SampleView(generics.RetrieveAPIView):
serializer_class = MyModelSerializer
# optional support of OpenAPI schema generation for Pydantic fields
schema = AutoSchema()
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 SchemaRenderer, SchemaParser, AutoSchema
@api_view(["POST"])
@parser_classes([SchemaParser[Foo]]):
@renderer_classes([SchemaRenderer[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 = [SchemaParser[Foo]]
renderer_classes = [SchemaRenderer[list[Foo]]]
# optional support of OpenAPI schema generation for Pydantic parsers/renderers
schema = AutoSchema()
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])
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
Close
Hashes for django-pydantic-field-0.1.7.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | efc470e86cf4364500ec1607cf293655fb629823bad17390ffd6afe1ce319a92 |
|
MD5 | b9c34d4e20e2e55453083f134a465c84 |
|
BLAKE2b-256 | 220c40c1c18a9b2c5367707b1da117e7a5281a6a57cfef17b9b53e0bd56e34b9 |
Close
Hashes for django_pydantic_field-0.1.7-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 99a7b0b13a943dceeb60d5a0b610518e9a33d154ad09fd50ddbcd521dfe29385 |
|
MD5 | f2b19e0dcc984e2af198f492bd02de61 |
|
BLAKE2b-256 | 52682eba209f77fdd20697b20157fdd3dc2d53c028b7973c1b4023d67ee9ce3c |