Django Pydantic Field
django-pydantic-field integrates Pydantic models with Django's JSONField, offering a type-safe and validated way to store complex data. It provides transparent support for both Pydantic v1 and v2, integrates with Django Forms and Django REST Framework, and enhances static type checking within Django projects. Currently at version 0.5.4, the library is actively maintained with a regular release cadence, addressing compatibility and bug fixes across Django and Pydantic versions.
Warnings
- breaking Support for Python 3.8 and 3.9 was dropped in version 0.4.0. Projects using these Python versions must either upgrade their Python environment or pin `django-pydantic-field` to a version prior to 0.4.0.
- breaking Pydantic v2 introduces significant breaking changes (e.g., `dict()` to `model_dump()`, `json()` to `model_dump_json()`, `Config` class to `model_config` dict). While `django-pydantic-field` aims for transparent support, direct interaction with Pydantic models in your application code will require migrating to Pydantic v2's API. Pydantic v1 is also incompatible with Python 3.14 and newer, forcing a Pydantic v2 migration if using newer Python versions.
- gotcha Serializing complex Pydantic types (e.g., union types like `list[Model] | None`, Pydantic v2 constrained types like `conint`, `Annotated` types, or nested dataclasses) within Django migrations can lead to infinite recursion or incorrect serialization. This has been a recurring issue fixed across several minor releases.
- gotcha In Pydantic v1, `Optional[Type]` implicitly defaulted to `None`. In Pydantic v2, `Optional[Type]` (or `Type | None`) means the field is required but can accept `None` as a valid value, not that it has a default of `None`. This can lead to unexpected validation errors if `null=True` is not explicitly set on `SchemaField` or if `default=None` is not provided in Pydantic.
- gotcha `django-pydantic-field` performs validation during Django's `manage.py check` command (e.g., `pydantic.E002: Default value serialization errors`). If your Pydantic schemas or their default values are not correctly serializable, Django's system checks will raise errors.
Install
-
pip install django-pydantic-field
Imports
- SchemaField
from django_pydantic_field import SchemaField
Quickstart
import pydantic
import typing
from django.db import models
from django_pydantic_field import SchemaField
# Define a Pydantic model
class Foo(pydantic.BaseModel):
count: int
slug: str = "default"
# Define a Django model using SchemaField
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 typing.Optional[Foo] for type checkers
optional_foo = SchemaField(Foo, null=True)
# Example usage (Django shell context assumed):
# obj = MyModel.objects.create(bar={'count': 10, 'slug': 'test-slug'}, foo={'count': 20}, items=[{'count': 1}, {'count': 2}])
# print(obj.bar.count) # Access Pydantic model attributes
# print(obj.foo.slug) # 'default'
# obj.bar = Foo(count=15, slug='new-slug') # Assign Pydantic model directly
# obj.save()