Skip to main content

Type-Safe Pydantic Schemas for Django JSONFields

Project description

PyPI Version Lint and Test Package PyPI - Downloads Supported Python Versions Supported Django Versions

Type-Safe Pydantic Schemas for Django JSONFields

django-pydantic-field provides a way to use Pydantic models as schemas for Django's JSONField. It offers full support for Pydantic v1 and v2, type safety and integration with Django's ecosystem, including Forms and Django REST Framework.

Highlights

  • Unified API: Transparent support for Pydantic v1 and v2 through the SchemaAdapters.
  • Type-Safe: Support for static type checking (ty/mypy/pyright) with type inference for models and annotations.
  • Forward References: Lazy resolution of forward references, allowing schemas to be defined anywhere.
  • Django Integration: Support for Django Forms and the Admin interface.
  • DRF Support: Typed Serializers, Parsers, and Renderers with automatic OpenAPI schema generation via DRF's native schema generator.

Installation

pip install django-pydantic-field

Basic Usage

The SchemaField can be used by passing the schema as the first argument (Django-like style) or by using type annotations.

import pydantic
import typing

from django.db import models
from django_pydantic_field import SchemaField


class Foo(pydantic.BaseModel):
    count: int
    slug: str = "default"


class MyModel(models.Model):
    # Django-like style (explicit schema)
    bar = SchemaField(Foo, default={"count": 5})

    # Annotation-based style (Pydantic-like)
    foo: Foo = SchemaField()

    # Supports standard Python types and annotations
    items: list[Foo] = SchemaField(default=list)

    # null=True correctly infers t.Optional[Foo] for type checkers
    optional_foo = SchemaField(Foo, null=True, default=None)

model = MyModel(foo={"count": 42})
model.save()

# Data is automatically parsed into Pydantic models
assert isinstance(model.foo, Foo)
assert model.foo.count == 42

typing.assert_type(model.optional_foo, Foo | None)

Supported Types

Any type supported by Pydantic can be used as a schema:

  • pydantic.BaseModel and pydantic.RootModel (v2)
  • Standard Python types (list[str], dict[int, float], etc.)
  • dataclasses.dataclass and TypedDict protocols
  • typing.Annotated with metadata.
from typing import Annotated
from pydantic import Field


class AdvancedModel(models.Model):
    # Annotated with validation rules
    positive_ints: Annotated[list[int], Field(min_length=1)] = SchemaField()

Forward References & Lazy Resolution

SchemaField supports forward references via string literals or typing.ForwardRef. Resolution is deferred until the first time the field is accessed.

import typing


class MyModel(models.Model):
    foo = SchemaField(typing.ForwardRef("DeferredFoo"))
    another_foo: "DeferredFoo" = SchemaField()


class DeferredFoo(pydantic.BaseModel):
    ...

Pydantic Version Support

The package automatically detects the Pydantic version in your environment and adapts accordingly.

For Pydantic v2 environments, you can still explicitly use Pydantic v1 models by importing from the .v1 subpackage:

from pydantic import v1 as pydantic_v1
from django_pydantic_field.v1 import SchemaField as SchemaFieldV1


class LegacySchema(pydantic_v1.BaseModel):
    ...


class LegacyModel(models.Model):
    legacy_field = SchemaFieldV1(LegacySchema)

Django Forms & Admin

It is possible to create Django forms, which would validate against the given schema:

from django import forms
from django_pydantic_field.forms import SchemaField


class FooForm(forms.Form):
    field = SchemaField(Foo)


form = FooForm(data={"field": '{"slug": "asdf", "count": 1}'})
assert form.is_valid()

django-jsonform support

For a better user experience in the Admin, you can use django-jsonform, which provides a dynamic editor based on the Pydantic model's JSON schema.

from django.contrib import admin
from django_pydantic_field import fields
from django_jsonform.widgets import JSONFormWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        fields.PydanticSchemaField: {"widget": JSONFormWidget},
    }

Django REST Framework

Serializers

from rest_framework import serializers
from django_pydantic_field.rest_framework import SchemaField


class MySerializer(serializers.Serializer):
    pydantic_field = SchemaField(Foo)

Typed Views (Parsers & Renderers)

You can use SchemaParser and SchemaRenderer to handle Pydantic models directly in your views.

from rest_framework.decorators import api_view, parser_classes, renderer_classes
from rest_framework.response import Response
from django_pydantic_field.rest_framework import SchemaParser, SchemaRenderer

@api_view(["POST"])
@parser_classes([SchemaParser[Foo]])
@renderer_classes([SchemaRenderer[list[Foo]]])
def foo_view(request):
    # request.data is a Foo instance
    instance: Foo = request.data
    return Response([instance])

OpenAPI Generation

django-pydantic-field provides an AutoSchema that automatically generates OpenAPI definitions for your Pydantic-backed DRF components.

from django_pydantic_field.rest_framework import AutoSchema

class SampleView(generics.RetrieveAPIView):
    serializer_class = MySerializer
    schema = AutoSchema()

System Checks

The field performs validation during Django's manage.py check command:

  • pydantic.E001: Schema resolution errors.
  • pydantic.E002: Default value serialization errors.
  • pydantic.W003: Data integrity warnings for include/exclude configurations.

Contributing

To get django-pydantic-field up and running in development mode:

  1. Install uv;
  2. Install the project and its dependencies: uv sync;
  3. Setup pre-commit: pre-commit install.
  4. Run tests: make test.
  5. Run linters: make lint.

Acknowledgement

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

django_pydantic_field-0.5.4.tar.gz (22.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_pydantic_field-0.5.4-py3-none-any.whl (37.0 kB view details)

Uploaded Python 3

File details

Details for the file django_pydantic_field-0.5.4.tar.gz.

File metadata

  • Download URL: django_pydantic_field-0.5.4.tar.gz
  • Upload date:
  • Size: 22.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for django_pydantic_field-0.5.4.tar.gz
Algorithm Hash digest
SHA256 3c884299ea777e8221e4c0ff222e078960ba3576a3b6970636629524e5d6cf39
MD5 ad84a191db65288c7ea698d0fd4fe582
BLAKE2b-256 423dd2390f1383eb60b25c7b68b3493af566831b0db540e47ed85a395727bae2

See more details on using hashes here.

File details

Details for the file django_pydantic_field-0.5.4-py3-none-any.whl.

File metadata

  • Download URL: django_pydantic_field-0.5.4-py3-none-any.whl
  • Upload date:
  • Size: 37.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for django_pydantic_field-0.5.4-py3-none-any.whl
Algorithm Hash digest
SHA256 5c080b5f0ea17ae11b5305d649778a87437c61a403894933337fe3e295f627a9
MD5 112ab1880409d6ed031e3018ebb4234f
BLAKE2b-256 ab881acbef013f172f9f03836d3c03639ae5604a46e9f1a921c6e623e60f8594

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page