Django — greenfield or existing project¶
Use hedron-django for Django-native apps. Requires Django >=5.2,<6.
Scaffold with the hedron CLI (hedron new --django); runtime is
hedron-django + hedron-core (no FastAPI in the app process). The adapter
mounts /hedron-static so PAGE responses can inject bundled HTMX.
Install: pip install "hedron-django>=1.0.0" (or uv add "hedron-django>=1.0.0").
Requires Python 3.11–3.14. See Installation.
Django supports AppConfig, forms, and QuerySet DataSource. Progressive FastAPI
facades (@app.view, @app.action, and related symbols) are FastAPI-only —
see the host matrix on What’s ready.
Golden path (scaffold + Refresh)¶
Same success criteria as FastAPI: open the app, see Hello, click Refresh, watch
the status region update without a full page reload. The scaffold uses Django views
and raw hx-* attributes, not FastAPI status.refresh_button(...).
# Need uv? https://docs.astral.sh/uv/getting-started/installation/
uvx --from "hedron>=1.0.0" hedron new my-django-app --django
cd my-django-app && uv sync
uv run waitress-serve --listen=127.0.0.1:8000 wsgi:application
Open http://127.0.0.1:8000 — you should see
Hello from hedron new --django. Click Refresh; the panel timestamp updates
via HTMX into the declared #panel region.
The scaffold includes page + fragment regions and security headers middleware.
Set HEDRON_SESSION_SECRET before production.
refresh_button vs raw hx-*
FastAPI scaffolds use status.refresh_button(...). Django getting-started samples may show
raw hx-get / hx-target attributes — both are valid across adapters.
Try without local setup
Open the monorepo in Codespaces / Dev Container, then
scaffold with hedron new my-app --django or run the reference slice below.
Alternate: clone the reference¶
git clone https://github.com/eddiethedean/hedron.git
cd hedron
uv sync
cd examples/django-reference
uv run waitress-serve --listen=127.0.0.1:8000 wsgi:application
Open http://127.0.0.1:8000/. Source:
examples/django-reference.
ASGI: uv run uvicorn asgi:application --host 127.0.0.1 --port 8000.
Existing Django project (add a Refresh page)¶
Add hedron_django to INSTALLED_APPS when you need forms/QuerySet helpers.
Keep SessionMiddleware and CsrfViewMiddleware for production Django CSRF.
Minimal Refresh-capable view:
# demo/views.py
from datetime import datetime, timezone
from django.http import HttpRequest
from django.urls import path
from hedron_core import FragmentRegion, InteractionResult, Page, Text, html
from hedron_core.interaction import InteractionPolicy
from hedron_django import page, view
PANEL = FragmentRegion(id="panel", selector="#panel")
def panel_body() -> object:
stamp = datetime.now(timezone.utc).strftime("%H:%M:%S UTC")
return html.div(Text(f"Django status · {stamp}"), id="panel")
@page
def home(request: HttpRequest):
return Page(
html.div(
Text("Hello Django"),
panel_body(),
html.button(
Text("Refresh"),
**{
"hx-get": "/status",
"hx-target": "#panel",
"hx-swap": "outerHTML",
},
),
),
title="Home",
)
@view(fragment_regions=(PANEL,))
def status(request: HttpRequest):
return InteractionResult(
content=panel_body(),
region_id="panel",
policy=InteractionPolicy(declared_regions=(PANEL,)),
)
urlpatterns = [
path("", home, name="home"),
path("status", status, name="status"),
]
Wire urlpatterns into your ROOT_URLCONF, then python manage.py runserver.
Portable CSRF header¶
HedronDjango.validate_csrf accepts both Django's X-CSRFToken and Hedron's portable
X-CSRF-Token. For stock Django middleware alone, HTMX clients that send only the portable
header should set::
in Django settings (as the reference app does).
Stock Django's X-CSRFToken remains valid if you keep the default.
Form posts must use csrfmiddlewaretoken. Django's CsrfViewMiddleware does not
accept Hedron's portable csrf_token field name.
Next¶
Stay on Django: extend the canonical @page / @view decorators and POST with csrfmiddlewaretoken. Prefer
polling for job status.
FastAPI-only continuation
HTMX interactions and
Minimal form assume Hedron() / CsrfField()
(csrf_token). Use them after you switch hosts.
- Security · Ship a Hedron app
- Forms:
hedron_django.forms.form_to_nodes/validation_interaction - QuerySets:
hedron_data.DjangoQuerySetDataSourcewith an already-authorized base QS