使用 HTMX 完成刪除功能的邏輯解析
更新日期: 2024 年 12 月 1 日
本文為 Django 與前端框架教學,第 3 篇:
- 使用 Esbuild 實現 Django 中的靜態資源管理與優化
- 使用 HTMX 實現 Django 頁面不刷新交互效果
- 使用 HTMX 完成刪除功能的邏輯解析 👈 所在位置
- 使用 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 選擇器,用於向上搜索最近的符合條件的祖先節點。如果希望更改更新範圍,可以調整為其他選擇器(例如body
、parent
等)。
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 與後端協作完成刪除的具體步驟:
- 用戶點擊「刪」按鈕:
- HTMX 偵測到按鈕的
hx-post
屬性,發送 POST 請求至 URL,例如/comments/5
。
- HTMX 偵測到按鈕的
- 顯示刪除確認框:
- HTMX 彈出
hx-confirm
設置的確認框。 - 如果使用者點擊「確認」,請求才會發送至後端。
- HTMX 彈出
- 後端接收請求:
- Django 視圖函數透過 URL 獲取
comment.id
,查詢並刪除對應的 Comment。
- Django 視圖函數透過 URL 獲取
- 後端返回空回應:
- 後端回應為空字串
HttpResponse("")
。
- 後端回應為空字串
- HTMX 處理回應:
- HTMX 根據
hx-target="closest li"
找到目標<li>
,並使用回應的空字串替換整個元素。 - 因回應為空,目標元素直接從 DOM 中被移除。
- HTMX 根據
總結
- 動態更新的優勢:
- 使用 HTMX,我們只需返回 HTML 片段即可完成刪除操作,省去前端手動操作 DOM 的複雜性。
- 提高效能:
- 只需更新需要刪除的部分(單個
<li>
),而不是重新渲染整個留言列表。
- 只需更新需要刪除的部分(單個
- 簡化代碼:
- 利用 HTMX 的 HTML 屬性設置,可以減少 JavaScript 的使用,維護性更高。