Django 表單:如何讓使用者選擇性提交星星評分與留言

更新日期: 2025 年 1 月 7 日

在 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

說明:

  1. def __init__(self, *args, **kwargs)
    • 這是 Python 中的建構子方法,當表單被初始化時會自動執行。
    • *args**kwargs 允許接收多個參數,用於靈活地處理表單初始化時的各種情況。
  2. super().__init__(*args, **kwargs)
    • 呼叫父類別 (forms.ModelForm) 的初始化方法,以確保原生的表單初始化邏輯不被覆蓋。
  3. self.fields["content"].required = False
    • self.fields 代表這個表單的所有欄位集合。
    • required = False 表示該欄位不是必填的,使用者可以選擇不輸入內容。

為什麼這樣可以完成目標?

  1. 靈活控制表單驗證
    • content 設為非必填欄位,讓使用者可以僅提交 rating
  2. 保持 rating 為必要欄位
    • 由於 forms.py 中沒有對 rating 使用 required=False,因此 rating 欄位仍然是必填的。
  3. 確保前後端一致性
    • 使用者提交表單時,Django 會自動檢查 required 屬性,避免不必要的後端錯誤。

測試與驗證

測試場景:

  • 僅提交星星評分 → 成功儲存
  • 同時提交留言與星星 → 成功儲存
  • 未填寫任何欄位 → 返回錯誤訊息
  • 僅提交留言 → 返回錯誤訊息

後端測試:

python manage.py shell
>>> from comments.models import Comment
>>> Comment.objects.all().values('content', 'rating')

總結

這樣的設計不僅符合「可選填留言」的需求,還確保了使用者體驗的靈活性與資料的完整性。如果有進一步的修改需求,隨時歡迎詢問!🚀

Similar Posts

發佈留言

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