使用 HTMX 完成刪除功能的邏輯解析

更新日期: 2024 年 12 月 1 日

本文為 Django 與前端框架教學,第 3 篇

  1. 使用 Esbuild 實現 Django 中的靜態資源管理與優化
  2. 使用 HTMX 實現 Django 頁面不刷新交互效果
  3. 使用 HTMX 完成刪除功能的邏輯解析 👈 所在位置
  4. 使用 Tailwind CSS 和 Shared Template 設計 Django 項目導航欄與樣式

建議閱讀本文前,先閱讀完 Django 高階教學 系列文

檔案目錄與功能說明

HTMX 是一個前端框架,可以幫助我們使用少量 HTML 和後端實現互動,無需 JavaScript。

以下是功能相關的檔案及用途:

  • comments/templates/comments/_comment.html:顯示單個留言的模板。
  • comments/views.py:後端處理刪除請求的邏輯。
  • comments/urls.py:路由配置,將前端請求指向對應的後端視圖函數。

修改後的 _comment.html 範例

以下是刪除功能的 HTML 模板代碼,包含 HTMX 的屬性:

<li>
  {{ comment.content|linebreaks }}
  <form hx-target="closest li"
        hx-swap="outerHTML"
        hx-confirm="確認刪除?"
        hx-post="{% url 'comments:delete' comment.id %}">
    {% csrf_token %}
    <button></button>
  </form>
  {{ comment.created_at }}
</li>

關鍵屬性解析

1. hx-post

  • 功能
    該屬性用於向指定的 URL 發送一個 POST 請求,這是 HTMX 提供的核心功能之一。通過 hx-post,可以輕鬆實現表單提交或觸發後端操作而無需手動撰寫 JavaScript。
  • 此處用法
    {% url 'comments:delete' comment.id %} 是 Django 模板語法,用於生成動態 URL。
    例如,當 comment.id 為 5 時,該語法會生成 /comments/5,這個 URL 指向與刪除視圖相關的後端處理邏輯。
  • 注意事項
    • 確保後端視圖設置為接受 POST 請求並處理刪除邏輯。
    • Django 視圖通常需要 CSRF 驗證,因此模板內包含 {% csrf_token %}

2. hx-target="closest li"

  • 功能
    此屬性用於指定 HTMX 更新的目標 DOM 節點。在這裡,目標為當前 <li> 元素,因為 closest li 指向與按鈕所在表單最近的父 <li> 節點。
  • 實現效果
    當後端回傳響應時,HTMX 會將對應的 <li> 整體替換。對於刪除操作,後端通常回傳空字串,這意味著 HTMX 會將該 <li> 從 DOM 中完全移除。
  • 使用情境
    closest 是 CSS 選擇器,用於向上搜索最近的符合條件的祖先節點。如果希望更改更新範圍,可以調整為其他選擇器(例如 bodyparent 等)。

3. hx-swap="outerHTML"

  • 功能
    定義 HTMX 如何將後端返回的響應應用到指定的目標元素。
  • outerHTML 的作用
    使用該設置時,返回的響應會替換目標元素本身,包括該元素的開頭標籤和結尾標籤。
  • 此處應用
    由於目標元素是 <li>,當後端返回空響應時(''),整個 <li> 標籤會被移除,從而達到刪除的效果。
  • 其他選項
    • innerHTML:僅替換目標元素的內容,不會影響外部標籤。
    • beforebegin / afterend 等:可插入新內容到目標元素的前後。

4. hx-confirm="確認刪除?"

  • 功能
    提供操作前的彈窗確認。只有使用者點擊「確認」按鈕後,HTMX 才會繼續發送請求。
  • 用法細節
    • 當點擊表單內的刪除按鈕時,HTMX 首先觸發彈窗,顯示「確認刪除?」這一訊息。
    • 使用者若選擇「取消」,請求將被終止,刪除動作不會執行。
    • 該屬性適用於任何需要簡單確認的場景,例如刪除、登出、重置設定等。
  • 替代方案
    如果需要更複雜的確認對話框,可以使用 JavaScript 與自訂 UI,但需要額外編寫腳本代碼。

後端邏輯解析

在後端,我們處理刪除請求並返回空的 HTTP 回應。

視圖函數

檔案位置:comments/views.py

from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from .models import Comment

def delete_comment(request, id):
    if request.method == "POST":
        # 找到對應的 Comment
        comment = get_object_or_404(Comment, id=id)
        comment.delete()

        # 返回空的 HTTP 回應,HTMX 將使用該回應替換目標元素
        return HttpResponse("")

路由配置

檔案位置:comments/urls.py

from django.urls import path
from . import views

app_name = "comments"

urlpatterns = [
    path("<int:id>", views.delete_comment, name="delete"),
]

刪除邏輯的運作流程

以下是 HTMX 與後端協作完成刪除的具體步驟:

  1. 用戶點擊「刪」按鈕
    • HTMX 偵測到按鈕的 hx-post 屬性,發送 POST 請求至 URL,例如 /comments/5
  2. 顯示刪除確認框
    • HTMX 彈出 hx-confirm 設置的確認框。
    • 如果使用者點擊「確認」,請求才會發送至後端。
  3. 後端接收請求
    • Django 視圖函數透過 URL 獲取 comment.id,查詢並刪除對應的 Comment。
  4. 後端返回空回應
    • 後端回應為空字串 HttpResponse("")
  5. HTMX 處理回應
    • HTMX 根據 hx-target="closest li" 找到目標 <li>,並使用回應的空字串替換整個元素。
    • 因回應為空,目標元素直接從 DOM 中被移除。

總結

  1. 動態更新的優勢
    • 使用 HTMX,我們只需返回 HTML 片段即可完成刪除操作,省去前端手動操作 DOM 的複雜性。
  2. 提高效能
    • 只需更新需要刪除的部分(單個 <li>),而不是重新渲染整個留言列表。
  3. 簡化代碼
    • 利用 HTMX 的 HTML 屬性設置,可以減少 JavaScript 的使用,維護性更高。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *