Instantiate Pydantic models directly from Django HttpRequest for request validation
Project description
Skip the serializer. Validate Django requests with Pydantic models — one line, zero boilerplate.
Documentation: https://django-pydantic.readthedocs.io
Source Code: https://github.com/NEFORCEO/django-pydantic
django-pydantic-client lets you replace manual request parsing in Django views with Pydantic models. Pass a HttpRequest directly to your schema — get a fully validated, typed Python object back, or an automatic HTTP 422 response if validation fails.
Key features:
- One-line validation —
data = MySchema(request) - Automatic 422 errors — middleware converts
ValidationErrorto structured JSON, no try/except needed - Smart data merging — GET params + POST form / JSON body + URL kwargs, all in one object
- Zero configuration — middleware auto-installs via
INSTALLED_APPS, nothing else to do - Full Pydantic v2 — validators,
Field(),model_config, computed fields, custom types
Requirements
- Python 3.10+
- Django 4.2+
- Pydantic 2.0+
Installation
pip install django-pydantic-client
Add to INSTALLED_APPS — that's the only configuration step:
# settings.py
INSTALLED_APPS = [
...
"django_pydantic",
]
PydanticValidationMiddleware is injected automatically. You do not need to touch MIDDLEWARE.
Quick start
Define a schema:
# myapp/schema.py
from pydantic import EmailStr, Field
from django_pydantic import RequestModel
class SignupSchema(RequestModel):
username: str = Field(min_length=3, max_length=32)
email: EmailStr
age: int = Field(ge=18)
Use it in a view:
# myapp/views.py
from django.http import JsonResponse
from .schema import SignupSchema
def signup(request):
data = SignupSchema(request) # validates GET / POST / JSON body
# data.username, data.email, data.age — typed and validated
return JsonResponse({"username": data.username})
Wire up the URL:
# urls.py
from django.urls import path
from myapp.views import signup
urlpatterns = [
path("signup/", signup),
]
On invalid input the response is automatic — no extra code required:
{
"detail": [
{"type": "missing", "loc": ["username"], "msg": "Field required"},
{"type": "value_error", "loc": ["email"], "msg": "value is not a valid email address"}
]
}
How data sources are merged
| Source | When used |
|---|---|
request.GET |
Always (any HTTP method) |
request.POST |
Non-GET/HEAD/DELETE, no JSON content-type |
| JSON body | Content-Type: application/json |
| URL kwargs | Passed explicitly: MySchema(request, pk=pk) |
Later sources override earlier ones. URL kwargs always win.
URL path parameters
# urls.py
path("users/<int:pk>/", user_detail)
# views.py
def user_detail(request, pk):
data = UserSchema(request, pk=pk) # pk merged with highest priority
user = User.objects.get(pk=data.pk)
...
Full Pydantic v2 support
from pydantic import Field, field_validator, computed_field
from django_pydantic import RequestModel
class OrderSchema(RequestModel):
product_id: int = Field(gt=0)
quantity: int = Field(ge=1, le=100)
coupon: str = ""
@field_validator("coupon")
@classmethod
def normalise_coupon(cls, v: str) -> str:
return v.strip().upper()
@computed_field
@property
def total_label(self) -> str:
return f"{self.quantity}x product #{self.product_id}"
Class-based views
from django.views import View
from django.http import JsonResponse
from .schema import ArticleCreateSchema
class ArticleView(View):
def post(self, request):
data = ArticleCreateSchema(request)
article = Article.objects.create(
title=data.title,
body=data.body,
author=request.user,
)
return JsonResponse({"id": article.pk}, status=201)
Error handling (opt-in)
The middleware handles errors automatically. To customise for a specific view:
from pydantic import ValidationError
def signup(request):
try:
data = SignupSchema(request)
except ValidationError as exc:
errors = {e["loc"][0]: e["msg"] for e in exc.errors(include_url=False)}
return JsonResponse({"errors": errors}, status=400)
return JsonResponse({"ok": True})
License
This project is licensed under the terms of the MIT license.
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_pydantic_client-0.1.1.tar.gz.
File metadata
- Download URL: django_pydantic_client-0.1.1.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb13014111f74d4a3eab190f09e6f2027330a68e309d10b80dc7cbdbd635bb1b
|
|
| MD5 |
f6e77193bc9c95c216be476bfd8558d4
|
|
| BLAKE2b-256 |
82fd03b99c53da8c71d7b1f776d75e0c13ba8b5f206d7d5b1ddf38ebab044c5c
|
File details
Details for the file django_pydantic_client-0.1.1-py3-none-any.whl.
File metadata
- Download URL: django_pydantic_client-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c40c76dba51b1e0cc77d887848ced1812ac55278bfe5c0a89002196d9aa8337
|
|
| MD5 |
ee32e9ad42098243310cb29b85afc1e7
|
|
| BLAKE2b-256 |
9c250becd1b70e2011defd13b2a85a844b121ed374247ed29fec6470b7f654f8
|