django-htmx

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Django HTMX

Django HTMX

Use HTMX to keep Django templates, views, forms, permissions, and server-side validation in charge while adding focused partial-page updates. Prefer plain Django first, then add the smallest HTMX behavior that improves the workflow.
In generated django-saas-starter projects:
  • django-htmx
    is installed and
    django_htmx.middleware.HtmxMiddleware
    adds
    request.htmx
    .
  • htmx.min.js
    is copied from npm to
    frontend/static/vendors/js/
    and loaded by
    frontend/templates/base_app.html
    and
    frontend/templates/base_landing.html
    .
  • The base templates already add
    X-CSRFToken
    during
    htmx:configRequest
    and set
    window.htmx.config.historyRestoreAsHxRequest = false
    . Do not duplicate this setup in feature templates.
  • Use Alpine.js only for browser-local state such as menus, modals, disclosure state, and lightweight transitions.
使用HTMX在保留Django模板、视图、表单、权限和服务端验证主导地位的同时,添加针对性的局部页面更新。优先使用原生Django实现,再添加最小化的HTMX行为来优化工作流。
在基于django-saas-starter生成的项目中:
  • 已安装
    django-htmx
    ,且
    django_htmx.middleware.HtmxMiddleware
    已添加
    request.htmx
    对象。
  • htmx.min.js
    已从npm复制到
    frontend/static/vendors/js/
    ,并由
    frontend/templates/base_app.html
    frontend/templates/base_landing.html
    加载。
  • 基础模板已在
    htmx:configRequest
    事件中添加
    X-CSRFToken
    ,并设置
    window.htmx.config.historyRestoreAsHxRequest = false
    。不要在功能模板中重复此配置。
  • 仅将Alpine.js用于浏览器本地状态管理,如菜单、模态框、展开/收起状态和轻量过渡效果。

Framework-Neutral HTMX Skills

框架无关的HTMX技能

Use these skills for deeper htmx guidance, then translate back to Django forms, views, templates, permissions, and tests:
  • htmx-endpoint-design
    for request/response contracts, targets, swaps, out-of-band updates, and events.
  • htmx-recipes
    for active search, pagination, infinite scroll, polling, dialogs, click-to-edit, boosted links, and other common patterns.
  • htmx-security
    for XSS, sanitization, CSP, CSRF, and htmx history-cache risk.
  • htmx-realtime
    for polling, SSE, and WebSocket tradeoffs.
  • htmx-interactivity
    for Alpine.js coordination, event boundaries, and local state outside replaceable targets.
  • htmx-js-api
    for programmatic requests,
    htmx.process
    , and event wiring.
以下技能可提供更深入的HTMX指导,之后可适配到Django的表单、视图、模板、权限和测试中:
  • htmx-endpoint-design
    :请求/响应契约、目标、替换操作、带外更新和事件处理。
  • htmx-recipes
    :实时搜索、分页、无限滚动、轮询、对话框、点击编辑、增强链接等常见模式。
  • htmx-security
    :XSS防护、内容清理、CSP、CSRF和HTMX历史缓存风险处理。
  • htmx-realtime
    :轮询、SSE和WebSocket的方案权衡。
  • htmx-interactivity
    :Alpine.js协同、事件边界和可替换目标外的本地状态管理。
  • htmx-js-api
    :程序化请求、
    htmx.process
    和事件绑定。

Resource Routing

资源路由

Load only the files needed for the current task:
NeedRead
Django view branching, response helpers, forms, validation
references/django-view-patterns.md
Template targets, swaps, OOB updates, Alpine events, recipe notes
references/template-interaction-patterns.md
Security rules, Django tests, response assertions, reference docs
references/testing-security.md
仅加载当前任务所需的文件:
需求参考文档
Django视图分支、响应助手、表单、验证
references/django-view-patterns.md
模板目标、替换操作、带外更新、Alpine事件、方案说明
references/template-interaction-patterns.md
安全规则、Django测试、响应断言、参考文档
references/testing-security.md

Implementation Workflow

实现流程

  1. Find the server state owner: model, queryset, form, service, permission, or session value.
  2. Choose the smallest URL boundary:
    • Reuse an existing view with
      request.htmx
      branching when the full page and partial share the same query and permissions.
    • Create a dedicated endpoint when the interaction has a narrow component contract or different mutation rules.
  3. Put reusable fragments in partial templates, commonly
    frontend/templates/<app>/partials/...
    or the local app template folder.
  4. Render the full page by including the same partial that the HTMX response returns.
  5. Preserve non-HTMX fallback behavior for links and forms whenever practical.
  6. Add tests for both normal and HTMX requests when the view branches on
    request.htmx
    .
  1. 确定服务端状态的归属:模型、查询集、表单、服务、权限或会话值。
  2. 选择最小化的URL边界:
    • 当完整页面和局部内容共享相同查询逻辑和权限时,复用现有视图并通过
      request.htmx
      分支处理。
    • 当交互有明确的组件契约或不同的变更规则时,创建专用端点。
  3. 将可复用片段放入局部模板,通常存放在
    frontend/templates/<app>/partials/...
    或本地应用模板文件夹中。
  4. 通过包含HTMX响应返回的同一局部模板来渲染完整页面。
  5. 尽可能为链接和表单保留非HTMX降级行为。
  6. 当视图通过
    request.htmx
    分支处理时,为普通请求和HTMX请求分别添加测试。

Django Rules

Django规则

  • Branch on
    request.htmx
    only after the same auth, permission, and data-loading path has run.
  • Use
    @vary_on_headers("HX-Request")
    on cacheable views that return different full-page and partial content for the same URL.
  • Prefer
    django_htmx.http
    helpers over hand-writing HTMX headers:
    HttpResponseClientRedirect
    ,
    HttpResponseClientRefresh
    ,
    HttpResponseLocation
    ,
    HttpResponseStopPolling
    ,
    push_url()
    ,
    replace_url()
    ,
    retarget()
    ,
    reswap()
    ,
    reselect()
    , and
    trigger_client_event()
    .
  • Keep Django forms as the validation source of truth. Include
    {% csrf_token %}
    in forms even when the base HTMX header is configured.
  • For invalid HTMX form submissions, return a rendered bound form with normal status
    200
    unless the project explicitly handles
    4xx
    or
    422
    swaps.
  • For destructive actions, require POST unless the project has a deliberate method override pattern for
    DELETE
    .
  • Keep the ownership line clear: HTMX owns server trips, fresh HTML, history updates, and cross-component server facts; Alpine owns local-only state, keyboard/menu behavior, temporary UI state, and transitions.
  • Use
    hx-push-url="true"
    only when the new state deserves a real browser URL, and ensure the pushed URL can render a full page on direct load and refresh.
  • 仅在完成相同的认证、权限校验和数据加载流程后,再通过
    request.htmx
    进行分支处理。
  • 对于同一URL返回不同完整页面和局部内容的可缓存视图,使用
    @vary_on_headers("HX-Request")
    装饰器。
  • 优先使用
    django_htmx.http
    助手函数而非手动编写HTMX响应头:
    HttpResponseClientRedirect
    HttpResponseClientRefresh
    HttpResponseLocation
    HttpResponseStopPolling
    push_url()
    replace_url()
    retarget()
    reswap()
    reselect()
    trigger_client_event()
  • 以Django表单作为验证的唯一可信来源。即使已配置HTMX基础CSRF头,仍需在表单中包含
    {% csrf_token %}
  • 对于无效的HTMX表单提交,返回渲染后的绑定表单并使用正常状态码
    200
    ,除非项目明确处理
    4xx
    422
    状态的替换操作。
  • 对于破坏性操作,要求使用POST方法,除非项目有针对
    DELETE
    的明确方法覆盖模式。
  • 明确职责边界:HTMX负责服务端请求、新鲜HTML、历史更新和跨组件服务端数据;Alpine.js负责纯本地状态、键盘/菜单行为、临时UI状态和过渡效果。
  • 仅当新状态需要真实浏览器URL时,才使用
    hx-push-url="true"
    ,并确保推送的URL在直接加载和刷新时能渲染完整页面。

Avoid

避坑指南

  • Do not return JSON for UI updates unless a non-HTMX API truly needs JSON.
  • Do not add React, Vue, or a client router for ordinary partial updates.
  • Do not place business logic in templates or browser event handlers.
  • Do not create one generic "htmx endpoint" that switches behavior based on arbitrary request parameters. Use explicit URLs and views.
  • Do not attach
    hx-trigger="keyup"
    or polling without debounce, throttle, or a clear stop condition.
  • Do not use HTMX to bypass Django's normal authentication, authorization, CSRF, form, or message patterns.
  • 除非非HTMX API确实需要JSON,否则不要返回JSON用于UI更新。
  • 对于普通的局部更新,不要引入React、Vue或客户端路由。
  • 不要在模板或浏览器事件处理器中放置业务逻辑。
  • 不要创建一个基于任意请求参数切换行为的通用“HTMX端点”,应使用明确的URL和视图。
  • 不要在未添加防抖、节流或明确停止条件的情况下,绑定
    hx-trigger="keyup"
    或轮询操作。
  • 不要使用HTMX绕过Django的常规认证、授权、CSRF、表单或消息机制。",