本文是Django基礎(5): 表單forms的設計與使用的進階篇。上文裡我們介紹了如何設計表單(forms),如何使用表單及進行表單驗證。這次我們將分享些Django表單的一些高級使用技巧。辛苦碼字不易,歡迎轉載點讚!
自定義欄位屬性和錯誤信息
對於每個欄位你可以設置其是否為必需,最大長度和最小長度。你還可以針對每個屬性自定義錯誤信息,見下面代碼。
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(
required=True,
max_length=20,
min_length=6,
error_messages={
'required': '用戶名不能為空',
'max_length': '用戶名長度不得超過20個字符',
'min_length': '用戶名長度不得少於6個字符',
}
)
password = forms.CharField(
required=True,
max_length=20,
min_length=6,
error_messages={
'required': '密碼不能為空',
'max_length': '密碼長度不得超過20個字符',
'min_length': '密碼長度不得少於6個字符',
}
)
對於基繼承ModelForm類的表單, 我們可以在Meta選項下widget中來自定義錯誤信息,如下面代碼所示:
from django.forms import ModelForm, Textarea
from myapp.models import Author
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
widgets = {
'name': Textarea(attrs={'cols': 80, 'rows': 20}), # 關鍵是這一行
}
labels = {
'name': _('Author'),
}
help_texts = {
'name': _('Some useful help text.'),
}
error_messages = {
'name': {
'max_length': _("This writer's name is too long."),
},
}
自定義表單輸入的widget和css屬性
Django forms的每個欄位你都可以選擇你喜歡的輸入widget,比如多選,複選框。你還可以定義每個widget的css屬性。如果你不指定,Django會使用默認的widget,有時比較醜。
比如下面這段代碼定義了表單姓名欄位的輸入控制項為Textarea,還指定了其樣式css。
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(
max_length=255,
widget=forms.Textarea(
attrs={'class': 'custom'},
),
)
設置widget可以是你的表單大大美化,方便用戶選擇輸入。比如下面案例裡對年份使用了SelectDateWidget,顏色則使用了複選框CheckboxSelectMultiple。單選可以用RadioSelect和Select。常見文本輸入可以用TextInput和TextArea。
from django import forms
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
COLORS_CHOICES = (
('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'),
)
class SimpleForm(forms.Form):
birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=COLORS_CHOICES,
)
表單數據初始化和實例化
有時我們需要對表單設置一些初始數據,我們可以通過initial方法,如下所示。
form = ContactForm(
initial={
'name': 'First and Last Name',
},)
其編輯修改類應用場景中,我們還要給表單提供現有對象的數據,而不是渲染一張空表單。這個過程叫表單與數據的結合。
對於由繼承ModelForm類的表單,我們可以按如下方法對表單進行實例化,如下面代碼所示:
contact = Contact.objects.get(id=1)
form = ContactForm(instance = contact)
對於自定義的表單,可以設置default_data。對於用戶提交的數據,括號裡可以使用request.POST。
default_data = {'name': 'John', 'email': 'someone@hotmail.com', }
form = ContactForm(default_data)
自定義表單驗證validators
對於表單驗證除了通過clean方法自定義驗證外,你還可以選擇自定義validators。例如下面案例中,如果用戶輸入的手機號不符合要求,表單就會返回手機號碼格式錯誤的驗證信息。
from django.core.exceptions import ValidationError
import re
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手機號碼格式錯誤')
class UserInfo(forms.Form):
email = forms.EmailField(error_messages={'required': u'郵箱不能為空'},)
mobile = forms.CharField(validators=[mobile_validate, ],
error_messages={'required': u'手機不能為空'},
widget=forms.TextInput(attrs={'class': "form-control",
'placeholder': u'手機號碼'}),)
一個頁面同時提交2張或多張表單
很多情況下我們希望用戶在同一頁面上點擊一個按鈕能同時提交2張或多張表單,這時我們可以在模板中給每個表單取不同的名字,如form1和form2(如下面代碼所示)。注: form1和form2分別對應forms.py裡的Form1()和Form2()。
<form >
{{ form1.as_p }}
{{ form2.as_p }}
</form>
然後用戶點擊提交後,我們就可以在視圖裡了對用戶提交的數據進行分別處理了,如下面代碼所示。
if request.method == 'POST':
form1 = Form1( request.POST,prefix="form1")
form2 = Form2( request.POST,prefix="form2")
if form1.is_valid() or form2.is_valid():
pass
else:
form1 = Form1(prefix="form1")
form2 = Form2(prefix="form2")