Django Fragment Patterns¶
Use the snippets as starting points for server-rendered fragments. Each recipe
keeps the request contract visible in the template: a real Django action, a
matching HTMX request attribute, an explicit target and swap, and a response
that renders the replacement fragment.
Query-driven views¶
Use htmx-search, htmx-filter-sort, and htmx-pagination for GET requests.
Keep filters in a form and use hx-include="this" so the query controls are
submitted with the request. Return the results fragment, not a full page, when
the request is an HTMX request.
<form method="get" action="{% url 'item-list' %}"
hx-get="{% url 'item-list' %}" hx-include="this"
hx-target="#results" hx-swap="outerHTML"
hx-sync="this:replace">
<input name="q" type="search" placeholder="Search">
<select name="ordering">
<option value="name">Name</option>
<option value="-created_at">Newest</option>
</select>
<button type="submit">Apply</button>
</form>
<section id="results">{% include "items/_partials/results.html" %}</section>
Pagination links should use the same results target and return the same root element. “Load more” can instead replace the triggering list item with the next page link; this avoids client-side accumulation logic.
Server-authoritative mutations¶
Use htmx-autosave, htmx-toggle, and htmx-soft-delete-undo for POST forms.
Include {% csrf_token %} and keep the native action and hx-post values in
sync. The view should authorize the mutation, then return the exact element
named by hx-target.
For validation failures, return the bound form or status fragment with HTTP 200. That response contract behaves consistently in HTMX 2 and HTMX 4.
Validation and suggestions¶
htmx-field-check is a GET-only field probe. htmx-autocomplete targets a
datalist fragment. Debounce and hx-sync="this:replace" keep stale responses
from winning when the user types quickly. Use aria-live="polite" for status
messages and keep the input's accessible label in the surrounding template.
Partials and response roots¶
Place reusable fragments in ordinary Django _partials/ includes, for example
items/_partials/results.html or items/_partials/item.html. Django 6
{% partialdef %} remains supported; choose one convention per project and
make the returned root stable so outerHTML replacements remain predictable.
See Django Response Contracts for view code, CSRF, uploads, response headers, and out-of-band fragments.