## 使用 [[Django]] 和 HTMX 簡化動態網頁開發:Form 與 Serializer 的應用 {#sec-b233da7ff7c9} 在上一篇文章中,我們探討了 **[[HTMX]] 將資料傳輸到伺服器的方式**。 **回顧前文**:[使用 Django 和 HTMX 簡化動態網頁開發 (第四部分):Payload 傳輸方式](/ko/whitedec/2025/1/27/django-htmx-csrf-token-integration/) 我們確認了,如果說傳統 JavaScript 的 `fetch()` 更接近直接構建 JSON payload 並發送的方式,那麼 **HTMX 則更接近從 DOM 收集值並以 form-data 形式發送的方式**。 那麼,一個自然而然的問題就浮現了: **「針對 HTMX 傳入的這些資料,在 Django 中使用什麼來驗證會最自然呢?」** 起初,許多人可能會想到 **DRF Serializer**。確實,Serializer 是一個強大的驗證工具,即使不是 JSON 資料也能使用。但實際將其與 HTMX 搭配使用時,有時會感覺有些牽強。 這是為什麼呢? 原因很簡單。 **HTMX 的基本流程更貼近 HTML form 的世界,而 Django 中恰好已經存在專為該世界設計的 `Form`。** 在本文中,我們將整理 **在處理 HTMX 請求時,`Django Form` 和 `DRF Serializer` 各自可以如何應用**,以及 **哪種方式是更自然且實用的選擇**。  --- ## [[HTMX]] 傳送的資料本質上更接近「表單資料」 {#sec-8c911eee119a} 正如上一篇所探討的,HTMX 基本上會收集 HTML 元素的數值並傳送至伺服器。例如,傳送 `
``` 這個範例雖然非常簡單,卻很好地展示了 [[HTMX]] 和 Django Form 的契合度。 * 失敗時可以重新渲染整個表單 * 使用者輸入的值也能被保留 * 錯誤訊息會自然地顯示在欄位旁 如果是傳統的 `fetch()` + JSON + 手動 DOM 操作方式,為了實現這種流程可能需要編寫相當多的 JavaScript。然而,透過 HTMX 和 Django Form 的組合,僅需伺服器端程式碼和模板即可大幅簡化處理。 --- ## 那麼,Serializer 是不是就不需要了? {#sec-5f0d93fcd48a} 說 **「不需要 Serializer」** 可能有些過頭了,或許這樣表達會更好: **「不一定非得將 Serializer 作為預設選擇」**,您覺得如何? 實際上,在以下情況中,[[DRF]] Serializer 仍然具有十足的吸引力: * 專案中已廣泛積極使用 DRF 的情況 * 希望在 API 和伺服器渲染畫面中重用相同的驗證邏輯 * 輸入驗證邏輯複雜,且已在 Serializer 中良好組織的情況 * 未來計劃將相同功能暴露給行動應用程式或外部 API 的情況 換言之,Serializer 的問題不在於 **「HTMX 能不能用它?」**, 而是更接近 **「在這裡使用 Serializer,對整體架構來說是否有益?」**。 --- ## Serializer 也能使用 {#sec-bfbe9c61b12c} 例如,假設您已經有以下的 Serializer: ```python from rest_framework import serializers class TodoSerializer(serializers.Serializer): title = serializers.CharField(max_length=100) priority = serializers.IntegerField(min_value=1, max_value=5) ``` 在這種情況下,它也能充分應用於 HTMX 請求。 ```python from django.shortcuts import render def todo_create_with_serializer(request): if request.method == "POST": serializer = TodoSerializer(data=request.POST) if serializer.is_valid(): title = serializer.validated_data["title"] priority = serializer.validated_data["priority"] return render(request, "todos/partials/todo_item.html", { "title": title, "priority": priority, }) return render(request, "todos/partials/todo_form_serializer.html", { "errors": serializer.errors, "data": request.POST, }, status=400) ``` 如您所見,**技術上完全沒有問題。** 因為 Serializer 並非只能接收 JSON 資料的工具。 然而,這裡會顯現出微妙的差異。 使用 Form 時: * 輸入值得以保留 * 每個欄位獨立渲染 * 錯誤綁定 * 與模板的連接 這些都能自然地銜接。 反之,使用 Serializer 時: * 需要自行將 `serializer.errors` 解構以符合模板結構 * 需另外傳遞原始輸入值 * 開發者需要花更多心思處理與 HTML form 重新渲染的連接 也就是說,**雖然可以使用,但會增加一些手動操作**。 正是因為這一點,當與 [[HTMX]] 搭配使用時,Serializer 可能會顯得有些牽強。 --- ## 總結 {#sec-37e5d418cdb7} 在上一篇中,我們探討了 [[HTMX]] 如何傳送資料。而在本篇中,我們整理了如何在 Django 中最自然地驗證這些資料。 * HTMX 基本上與 form-data 配合良好 * Django Form 正是為此流程設計的工具 * 因此,單就與 HTMX 的契合度而言,Form 是最自然的選擇 * DRF Serializer 雖然可以使用,但更偏向於策略性的選擇 我個人認為,要充分利用 HTMX,不僅需要培養 **「以 HTML 方式處理 AJAX 的感覺」**,還需要重新掌握 **「運用 Django Form 和 form tags 的技巧」**。 --- **相關閱讀** * [使用 Django 和 HTMX 簡化動態網頁開發 (第一部分)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification/) * [使用 Django 和 HTMX 簡化動態網頁開發 - Ajax (第二部分)](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-2/) * [使用 Django 和 HTMX 簡化動態網頁開發 (第三部分):Django 整合方法](/ko/whitedec/2025/1/27/django-htmx-dynamic-web-simplification-3/) * [使用 Django 和 HTMX 簡化動態網頁開發 (第四部分):Payload 如何傳輸?](/ko/whitedec/2025/1/27/django-htmx-advanced-features/)