django-datastar
django-datastar provides small, focused integration points between Django and
Datastar:
- exact request classification through
Datastar-Request: true; - sync/async middleware-backed
request.datastarmetadata; and - an opt-in bridge that supplies Django CSRF tokens to qualifying Datastar backend-action requests.
It does not provide Datastar response or SSE APIs. Use
datastar-py
as a companion when those APIs are needed.
The
Datastar-Requestheader is client-controlled metadata. Never use it for authentication, authorization, permissions, or a CSRF bypass.
Installation
Install the package from PyPI:
python -m pip install django-datastar
To install a development checkout instead, run python -m pip install . from
the repository root.
Add the middleware before Django's CSRF middleware:
MIDDLEWARE = [
# ...
"django_datastar.middleware.DatastarMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
# ...
]
Use either the helper or the attached details in a view:
from django.http import HttpResponse
from django_datastar import DatastarHttpRequest
def update(request: DatastarHttpRequest) -> HttpResponse:
if request.datastar:
return HttpResponse("Datastar request")
return HttpResponse("ordinary request")
DatastarHttpRequest is an annotation for requests processed by the middleware;
Django still creates the actual request object.
If your project already defines a custom request type, declare the middleware attribute on that type instead:
from django.http import HttpRequest as DjangoHttpRequest
from django_datastar import DatastarDetails
class HttpRequest(DjangoHttpRequest):
datastar: DatastarDetails
Views can then use the project's HttpRequest annotation. This follows the
custom-request pattern recommended by django-stubs.
When middleware-backed request details are not needed, classify a request directly:
from django.http import HttpRequest
from django.http import HttpResponse
from django_datastar import is_datastar
def update(request: HttpRequest) -> HttpResponse:
if is_datastar(request):
return HttpResponse("Datastar request")
return HttpResponse("ordinary request")
Automatic CSRF headers
The bridge is optional. Add the app when you want its template tag and static module:
INSTALLED_APPS = [
# ...
"django_datastar",
]
Load the tag before your chosen Datastar bundle:
{% load django_datastar static %}
{% datastar_csrf %}
<script type="module" src="{% static 'js/datastar.js' %}"></script>
For nonce-based Content Security Policies:
{% datastar_csrf nonce=request.csp_nonce %}
The tag calls Django's CSRF token machinery and emits a masked token in the DOM,
so it works with CSRF_COOKIE_HTTPONLY=True. The external module reads that token
at request time and injects X-CSRFToken only when all of these conditions hold:
- the effective method is unsafe;
Datastar-Requestis exactlytrue;- the effective target is same-origin;
- the request mode is compatible with
same-origin; - no CSRF header was supplied explicitly; and
- a DOM token is present.
Django's CsrfViewMiddleware remains solely responsible for validation. The
bridge assumes Datastar resolves window.fetch at request time; see the
compatibility documentation
before upgrading Datastar.
Example application
A small, database-free Django project demonstrates exact request-metadata classification, ordinary HTML morphs, and CSRF-protected Datastar POSTs. See the example guide and run it from the repository root:
uv run python example/manage.py runserver
Documentation
Build the documentation locally with:
python -m pip install ".[docs]"
sphinx-build -W --keep-going -b html docs docs/_build/html
Development
uv sync --group dev
uv run pytest
uv run python example/manage.py check
uv run python example/manage.py test example
node --test tests/test_datastar_csrf.mjs
uv run ruff check .
uv run ruff format --check .
uv run mypy
Node is contributor and CI tooling only. It is not a runtime dependency for Django applications.
License
MIT
Metadata
Release files for django-datastar 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_datastar-0.1.1.tar.gz | 36.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_datastar-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.5 kB
Release files / django_datastar-0.1.1.tar.gz
| Download URL | django_datastar-0.1.1.tar.gz |
|---|---|
| Size | 36.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1fbd81eea119981f2f9b543c11d3884c53f7f53e2d25e3a37fd86d041a48dcaa
|
|
BLAKE2b-256 checksum How to use checksums |
c4ca8ed835756c4e571551e4d577d5f34d2d6de8ca5b077915e2d70dfd89f6bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / django_datastar-0.1.1-py3-none-any.whl
| Download URL | django_datastar-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
728c95013148cb4452d70911a11479f90eb8805230774fb31efd6cc10e129649
|
|
BLAKE2b-256 checksum How to use checksums |
738c0ae30b66bc6987296f29dc8716656bfa0b1ed67a1c2eacb422910a67678e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log