Django ModelForm 筆記
Django ModelForm 筆記
✅ ModelForm 的目的與用途
Django 的 ModelForm
提供了一個方便的方法,讓我們可以快速根據模型創建表單。它自動從模型推導表單欄位,並進行表單驗證與資料處理。使用 ModelForm
可以減少手動創建表單類別的工作,提高開發效率。
📝 ModelForm 的常用設定
1. fields
/ exclude
model
: 指定是哪個 modelfields
: 指定哪些欄位會被包含在表單中。exclude
: 排除某些欄位,不會顯示在表單中。
class InterviewForm(ModelForm):
class Meta:
model = Interview
fields = ['company_name', 'position', 'interview_date', 'review', 'rating', 'result']
# exclude = ['is_admin'] # 不想包含的欄位
# fields = "__all__" 接受所有欄位,不建議這麼做
2. labels
可以自定義欄位顯示名稱:
labels = {
'company_name': '公司名稱',
'position': '職位',
'interview_date': '面試日期',
'review': '心得',
'rating': '評分',
'result': '面試結果'
}
3. widgets
控制欄位的輸入類型,特別針對日期或其他自定義輸入:
from django.forms import DateInput
widgets = {
'interview_date': DateInput(attrs={'type': 'date'})
}
💡 在 Views 中使用
ModelForm
可以幫助我們簡化新增與更新資料的邏輯:
新增資料
def index(req):
if req.POST:
form = InterviewForm(req.POST) # 沒有傳入 instance,代表要新增資料
interview = form.save() # 存入資料庫並回傳 instance
return redirect("interviews:show", id=interview.id)
else:
interviews = Interview.objects.order_by("-id")
return render(req, "interviews/index.html", {"interviews": interviews})
編輯資料
def show(req, id):
interview = get_object_or_404(Interview, pk=id)
if req.POST:
form = InterviewForm(req.POST, instance=interview) # 有傳入 instance,代表要更新資料
form.save()
return redirect("interviews:show", interview.id)
else:
comments = interview.comment_set.all()
return render(req, "interviews/show.html", {"interview": interview, "comments": comments})
預填表單(編輯頁面)
def edit(req, id):
interview = get_object_or_404(Interview, pk=id)
form = InterviewForm(instance=interview) # 預填現有資料
return render(req, "interviews/edit.html", {"interview": interview, "form": form})
🔄 創建 vs 更新資料
在使用 ModelForm
時,可透過 instance
參數來決定是要 創建 還是 更新 資料:
# 創建新的資料(不提供 instance)
form = InterviewForm(request.POST)
if form.is_valid():
form.save() # 會建立一筆新的 Interview 紀錄
# 更新既有資料(提供 instance)
form = InterviewForm(request.POST, instance=interview)
if form.is_valid():
form.save() # 會更新傳入的 interview 物件
- 不提供
instance
:form.save()
會執行INSERT
,新增一筆資料。 - 提供
instance
:form.save()
會執行UPDATE
,更新該物件的欄位。
🖥️ 在 Templates 中使用
<form method="post">
{% csrf_token %}
{{ form.as_p }} <!-- 將表單欄位渲染為段落 -->
<button type="submit">提交</button>
</form>
{{ form.as_p }}
:快捷渲染csrf_token
:防止 CSRF 攻擊
🎯 ModelForm 的優勢
- 自動生成表單欄位:無需手動一一定義。
- 自動資料驗證:根據模型欄位類型自動檢查輸入。
- 簡化新增與更新資料的邏輯:直接使用
form.save()
完成。 - 程式碼更簡潔、可維護性更高。