它接受用戶輸入的數據,進行驗證,並將這些數據存儲到資料庫中。
透過 Django 的表單系統可以輕鬆地創建和管理表單,大大簡化了表單 HTML 的生成和數據清除/驗證的過程。
我們可以使用 forms.Form
類來去創建一個聯絡表單
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(label='名字', max_length=100)
email = forms.EmailField(label='信箱')
message = forms.CharField(widget=forms.Textarea, label='問題訊息')
建立完後我們可以在視圖中去使用這個 form
from django.shortcuts import render
from .forms import ContactForm
from django.http import HttpResponseRedirect
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# 自定義處理表單數據
return HttpResponseRedirect('/thanks/')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
ModelForm 類是基於模型(Model)的表單,可以自動生成與模型對應的表單字段。
這樣做的好處是減少了重複的 code,確保表單字段與模型字段保持一致,寫法有點類似前面講到的 serializer。
首先,我們定義一個 CustomUser 模型,包含用戶名、電子郵件和密碼
from django.db import models
class CustomUser(models.Model):
username = models.CharField(max_length=150, unique=True)
email = models.EmailField(unique=True)
password = models.CharField(max_length=128)
def __str__(self):
return self.username
接著,我們要要在 app
底下創建 forms.py
來建立ModelForm 表單
from django import forms
from .models import CustomerUser
class UserRegistrationForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ['username', 'email', 'password']
widgets = {
'password': forms.PasswordInput(),
}
建立完後我們可以在視圖中去使用這個 form
from django.shortcuts import render, redirect
from .forms import UserRegistrationForm
def user_registration_view(request):
if request.method == 'POST':
form = UserRegistrationForm(request.POST)
if form.is_valid():
form.save() # 這裡可以直接將資料儲存到資料庫
return redirect('/welcome/')
else:
form = UserRegistrationForm()
return render(request, 'registration_form.html', {'form': form})
Django 提供了多種驗證機制來確保數據的有效性。
字段類型都自帶一些基本的驗證邏輯,比如 EmailField 會檢查輸入的內容是否是有效的電子郵件地址。
你可以透過覆寫表單類的方法來添加自定義驗證邏輯。例如,檢查兩個密碼字段是否一致:
from django import forms
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=100)
password1 = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get("password1")
password2 = cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("兩組密碼不一樣")
clean_<fieldname>
:這個好用的工具是去驗證單個字段,針對特定字段進行自定義驗證,fieldname
指的是欄位。
例如假設有一個用戶註冊表單,其中包括用戶名和電子郵件字段,我們希望確保用戶名不包含任何不允許的字符(例如,!、@、# 等符號)
from django import forms
class UserRegistrationForm(forms.Form):
username = forms.CharField(max_length=150)
email = forms.EmailField()
def clean_username(self):
username = self.cleaned_data.get('username')
if any(char in username for char in '!@#$%^&*()'):
raise forms.ValidationError("名字不能包含以下符號 !@#$%^&*()")
return username
這裡我們就接著使用 ModelForm 範例往下實作
先在 urls.py
中添加對應的 URL 配置
from django.urls import path
from .views import user_registration_view
from django.shortcuts import render
urlpatterns = [
path('register/', user_registration_view, name='register'),
path('welcome/', lambda request: render(request, 'welcome.html'), name='welcome'),
]
需要在 registration_form.html
模板中顯示表單,並處理用戶的輸入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Registration</title>
</head>
<body>
<h1>User Registration</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
{% if form.errors %}
<div>
<h3>Errors:</h3>
<ul>
{% for field in form %}
{% for error in field.errors %}
<li>{{ field.label }}: {{ error }}</li>
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}
</body>
</html>
當用戶成功註冊後,可以重定向到一個歡迎頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome</title>
</head>
<body>
<h1>Welcome!</h1>
<p>Your account has been created successfully.</p>
</body>
</html>
成果展示:(程式寫完記得要做 migrate)
進到註冊的畫面輸入資訊進行註冊:
成功註冊後會進到歡迎畫面:
資料庫中也會新增一筆註冊的資料:
今天我們學習了如何使用 Django 的表單系統來創建和管理表單,以及如何使用 ModelForm 類來建立與模型對應的表單字段,以及展示實作成果。下一篇文章我們將會介紹 Class-based Views