Add your description here
Project description
Django forms from Pydantic models
django-schemaform lets you define your form schema once using Pydantic and get a fully-featured Django form with automatic field mapping, constraints, and validation.
Installation
uv add django-schemaform
Or with pip:
pip install django-schemaform
Quick Start
Define a Pydantic model and create a form:
from pydantic import BaseModel, EmailStr, Field
from schemaform import SchemaForm
class ContactSchema(BaseModel):
name: str = Field(min_length=2, max_length=100)
email: EmailStr
message: str = Field(min_length=10, description="Your message to us")
class ContactForm(SchemaForm):
class Meta:
schema = ContactSchema
Use it in your Django view:
from django.shortcuts import render, redirect
def contact_view(request):
if request.method == "POST":
form = ContactForm(request.POST)
if form.is_valid():
data = form.validated_data # Pydantic model instance
# process data...
return redirect("success")
else:
form = ContactForm()
return render(request, "contact.html", {"form": form})
That's it! The form automatically:
- Maps
str→CharField,EmailStr→EmailField - Applies
min_length/max_lengthconstraints - Uses the
descriptionas help text - Validates through Pydantic on submit
Field Type Mapping
Core Python Types
| Python Type | Django Field |
|---|---|
str |
CharField |
int |
IntegerField |
float |
FloatField |
bool |
BooleanField |
Decimal |
DecimalField |
date |
DateField |
time |
TimeField |
datetime |
DateTimeField |
timedelta |
DurationField |
UUID |
UUIDField |
Pydantic Types
| Pydantic Type | Django Field |
|---|---|
EmailStr |
EmailField |
HttpUrl |
URLField |
AnyUrl |
URLField |
SecretStr |
CharField (password widget) |
Json |
JSONField |
PastDate |
DateField |
FutureDate |
DateField |
PastDatetime |
DateTimeField |
FutureDatetime |
DateTimeField |
File Upload Types
| SchemaForm Type | Django Field |
|---|---|
FileUpload |
FileField |
ImageUpload |
ImageField |
from schemaform import SchemaForm, FileUpload, ImageUpload
class UploadSchema(BaseModel):
document: FileUpload
photo: ImageUpload | None = None # Optional
Choice Fields
| Python Type | Django Field |
|---|---|
Literal["a", "b", "c"] |
ChoiceField |
enum.Enum subclass |
ChoiceField |
from typing import Literal
from enum import Enum
class Priority(str, Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class TaskSchema(BaseModel):
status: Literal["pending", "done"]
priority: Priority
category: Priority | None = None # Optional - adds empty choice
Constraint Mapping
| Pydantic Constraint | Django Field Attribute |
|---|---|
min_length |
min_length |
max_length |
max_length |
ge / gt |
min_value |
le / lt |
max_value |
max_digits |
max_digits (Decimal) |
decimal_places |
decimal_places (Decimal) |
pattern |
validators (RegexValidator) |
Labels and Help Text
Field metadata from Pydantic is automatically applied:
class ProfileSchema(BaseModel):
username: str = Field(
title="Username", # → label
description="Choose wisely" # → help_text
)
Validation
Single-Field Validation
Use Pydantic's @field_validator for field-level validation:
from pydantic import BaseModel, field_validator
from schemaform import SchemaForm, FileUpload
class UploadSchema(BaseModel):
resume: FileUpload
@field_validator("resume")
@classmethod
def validate_resume(cls, v):
if v.size > 5 * 1024 * 1024: # 5MB
raise ValueError("File must be under 5MB")
if not v.content_type == "application/pdf":
raise ValueError("Only PDF files allowed")
return v
Cross-Field Validation
Use @model_validator for validation across multiple fields:
from pydantic import BaseModel, SecretStr, model_validator
from schemaform import SchemaForm
class RegistrationSchema(BaseModel):
email: EmailStr
password: SecretStr = Field(min_length=8)
password_confirm: SecretStr
@model_validator(mode="after")
def passwords_match(self):
if self.password.get_secret_value() != self.password_confirm.get_secret_value():
raise ValueError("Passwords do not match")
return self
class RegistrationForm(SchemaForm):
class Meta:
schema = RegistrationSchema
Validation errors are automatically mapped to the appropriate form fields or to __all__ for non-field errors.
Demo Application
A demo Django application is included with example forms showcasing various features:
- Contact Form — Email, time fields, Literal choices
- User Registration — SecretStr passwords, PastDate, password matching validation
- Event Booking — Date/time, Decimal constraints, Enum choices, cross-field validation
- Product Review — UUID, integer rating with range, optional ImageUpload
- Job Application — FileUpload with validation, HttpUrl, Enum, Decimal
- Medical Appointment — FutureDatetime, Enum, sensitive data handling
See demo/README.md for setup instructions.
Requirements
- Python ≥ 3.12
- Django ≥ 5.2, < 6.0
- Pydantic ≥ 2.0, < 3.0
Contributing
Contributions are welcome! See CONTRIBUTING.md for development setup and guidelines.
License
BSD-3-Clause — see LICENSE.md for details.
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_schemaform-0.1.1.tar.gz.
File metadata
- Download URL: django_schemaform-0.1.1.tar.gz
- Upload date:
- Size: 23.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb8098dcc207857d58659dfde6573972352a3b688de9eb6cd9386fdf57a60fc2
|
|
| MD5 |
74f9a772ad2dc39246cee5654be3fca7
|
|
| BLAKE2b-256 |
11a9b9b73295121cedb46e58696f96442d6b7e0aa4ced3cadaf8e5ebea6ec3c7
|
File details
Details for the file django_schemaform-0.1.1-py3-none-any.whl.
File metadata
- Download URL: django_schemaform-0.1.1-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4af0bcef263f4ce0c1ae09833dd217cd58b702dccac2c3d6c95bf384b0f67c1
|
|
| MD5 |
00ab4da7b9ad679e4bdd9c278eb341b3
|
|
| BLAKE2b-256 |
b2bc874db80bfd9ca7d85b104b913b250cd5d8ebad6aec7df8038e083dca700f
|