Django 表單:如何讓使用者選擇性提交星星評分與留言
更新日期: 2025 年 1 月 7 日
本文為 留言評分功能 系列教學,第 1 篇:
- 使用 Django + Tailwind + Alpine.js 實作「五顆星評分」功能教學
- Django validators 驗證器完整教學
- Django PositiveSmallIntegerField 新手指南
- 在 esbuild 專案中整合 Alpine.js 的完整指南
- 使用 Alpine.js 建立星星評分表單 — 新手指南
- 深入理解 Alpine.js 中的 template 標籤使用指南
- Django 網站如何新增「星星評分」功能 — 後端接收邏輯
- Django 表單:如何讓使用者選擇性提交星星評分與留言 👈 所在位置
- Django 如何限制同一使用者只能對同一服務留言一次?
- Django 留言軟刪除邏輯|程式碼解析
- Django 計算評分摘要教學 — 使用 ORM 進行星等統計
- Python Django 使用 annotate、aggregate 統計教學
- 使用 Alpine.js 實作星級評分分佈 – 詳細教學
- Alpine.js 與 Tailwind CSS 動態樣式解析:為什麼有些樣式無法生效?
- Django 中使用 annotate() 與 Avg() 進行平均評分計算
在 Django 專案中,有時你可能需要讓使用者選擇性地提交「星星評分」或「星星評分與留言」。
這種情況下,後端需要進行適當的設定,確保資料正確儲存且不會強制要求同時提交兩者。
本篇文章將針對 Django 表單 (forms.py
) 進行詳細解釋,並說明如何使用 required=False
以及如何透過 __init__
方法來達成這個需求。
問題概述
需求:
- 使用者可以僅提交「星星評分」
- 使用者可以同時提交「星星評分與留言」
- 使用者不能僅提交留言
- 使用者不能完全空白提交
解決方案:
- 在
forms.py
允許content
欄位為可選。 - 在
views.py
驗證rating
是否有被提交,並根據不同情況儲存資料。
修改 forms.py
我們需要修改 forms.py
,將 content
設為可選欄位,並允許僅提交 rating
。
# forms.py
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ["content", "rating"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ✅ 將 content 設定為非必填欄位
self.fields["content"].required = False
__init__
方法的詳細解釋
在 Django 表單中,__init__
是表單的建構子方法,用於初始化表單的欄位行為。
程式碼拆解:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["content"].required = False
說明:
def __init__(self, *args, **kwargs)
:- 這是 Python 中的建構子方法,當表單被初始化時會自動執行。
*args
和**kwargs
允許接收多個參數,用於靈活地處理表單初始化時的各種情況。
super().__init__(*args, **kwargs)
:- 呼叫父類別 (
forms.ModelForm
) 的初始化方法,以確保原生的表單初始化邏輯不被覆蓋。
- 呼叫父類別 (
self.fields["content"].required = False
:self.fields
代表這個表單的所有欄位集合。required = False
表示該欄位不是必填的,使用者可以選擇不輸入內容。
為什麼這樣可以完成目標?
- 靈活控制表單驗證:
- 將
content
設為非必填欄位,讓使用者可以僅提交rating
。
- 將
- 保持
rating
為必要欄位:- 由於
forms.py
中沒有對rating
使用required=False
,因此rating
欄位仍然是必填的。
- 由於
- 確保前後端一致性:
- 使用者提交表單時,Django 會自動檢查
required
屬性,避免不必要的後端錯誤。
- 使用者提交表單時,Django 會自動檢查
測試與驗證
測試場景:
- ✅ 僅提交星星評分 → 成功儲存
- ✅ 同時提交留言與星星 → 成功儲存
- ✅ 未填寫任何欄位 → 返回錯誤訊息
- ✅ 僅提交留言 → 返回錯誤訊息
後端測試:
python manage.py shell
>>> from comments.models import Comment
>>> Comment.objects.all().values('content', 'rating')
總結
這樣的設計不僅符合「可選填留言」的需求,還確保了使用者體驗的靈活性與資料的完整性。如果有進一步的修改需求,隨時歡迎詢問!🚀