咱們以前在HTML頁面中利用form表單向後端提交數據時,都會寫一些獲取用戶輸入的標籤而且用form標籤把它們包起來。與此同時咱們在好多場景下都須要對用戶的輸入作校驗,好比校驗用戶是否輸入,輸入的長度和格式等正不正確。若是用戶輸入的內容有錯誤就須要在頁面上相應的位置顯示對應的錯誤信息。Django的form組件就實現了上面所述的功能。html
總結一下,其實form組件的主要功能以下:python
ps:django官方文檔-forms-apigit
經過下面註冊示例感覺一下普通方式和Form方式的差異。正則表達式
1 from django.conf.urls import url 2 from test_app import views 3 4 urlpatterns = [ 5 url(r'^register_html/', views.register_html), 6 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>註冊</title> 6 </head> 7 <body> 8 <form action="/register_html/" method="post"> 9 {% csrf_token %} 10 <table> 11 <tr> 12 <td style="text-align: right">用戶名:</td> 13 <td><input type="text" name="username" value="{{ username }}"></td> 14 <td style="color: red"> 15 {{ username_error }} 16 </td> 17 </tr> 18 <tr> 19 <td style="text-align: right">密碼:</td> 20 <td><input type="password" name="userpwd" value="{{ userpwd }}"></td> 21 <td style="color: red">{{ userpwd_error }}</td> 22 </tr> 23 <tr> 24 <td style="text-align: right">確認密碼:</td> 25 <td><input type="password" name="re_userpwd" value="{{ re_userpwd }}"></td> 26 <td style="color: red">{{ re_userpwd_error }}</td> 27 </tr> 28 <tr> 29 <td colspan="3" style="text-align: center"> 30 <input type="submit" value="提交"> 31 </td> 32 </tr> 33 </table> 34 </form> 35 </body> 36 </html>
1 from django.shortcuts import render, HttpResponse 2 3 4 def register_html(request): 5 if request.method == 'POST': 6 username = request.POST.get('username') 7 userpwd = request.POST.get('userpwd') 8 re_userpwd = request.POST.get('re_userpwd') 9 msg_dict = {'status': 'error', 'msg': '驗證失敗', 'username': username, 'userpwd': userpwd, 10 're_userpwd': re_userpwd} 11 # 限制用戶名長度爲6-12位 12 if len(username) < 6 or len(username) > 12: 13 msg_dict['username_error'] = '用戶名長度需爲6-12位' 14 print(msg_dict) 15 return render(request, 'register_html.html', msg_dict) 16 if len(userpwd) == 0: 17 msg_dict['userpwd_error'] = '密碼不能爲空' 18 return render(request, 'register_html.html', msg_dict) 19 # 確認兩次輸入密碼一致 20 if userpwd != re_userpwd: 21 msg_dict['re_userpwd_error'] = '兩次輸入的密碼必須一致' 22 return render(request, 'register_html.html', msg_dict) 23 # 上述驗證都經過,下面執行註冊操做 ... 24 return HttpResponse('註冊成功') 25 return render(request, 'register_html.html')
1 from django.conf.urls import url 2 from test_app import views 3 4 urlpatterns = [ 5 url(r'^register_form/', views.register_form), 6 ]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>註冊</title> 6 </head> 7 <body> 8 <form action="/register_form/" method="post" novalidate> 9 {% csrf_token %} 10 <table> 11 <tr> 12 <td style="text-align: right">{{ form_obj.username.label }}:</td> 13 <td>{{ form_obj.username }}</td> 14 <td style="color: red"> 15 {{ form_obj.username.errors.0 }} 16 </td> 17 </tr> 18 <tr> 19 <td style="text-align: right">{{ form_obj.userpwd.label }}:</td> 20 <td>{{ form_obj.userpwd }}</td> 21 <td style="color: red">{{ form_obj.userpwd.errors.0 }}</td> 22 </tr> 23 <tr> 24 <td style="text-align: right">{{ form_obj.re_userpwd.label }}:</td> 25 <td>{{ form_obj.re_userpwd }}</td> 26 <td style="color: red">{{ form_obj.re_userpwd.errors.0 }}</td> 27 </tr> 28 <tr> 29 <td colspan="3" style="text-align: center"> 30 <input type="submit" value="提交"> 31 </td> 32 </tr> 33 </table> 34 </form> 35 </body> 36 </html>
1 from django.shortcuts import render, HttpResponse 2 from django import forms 3 4 5 # 按照Django form組件的要求本身寫一個類 6 class RegForm(forms.Form): 7 username = forms.CharField( 8 label="用戶名", 9 min_length=6, 10 max_length=12, 11 initial="admin", 12 error_messages={ 13 "min_length": "用戶名長度需爲6-12位", 14 "max_length": "用戶名長度需爲6-12位", 15 } 16 ) 17 userpwd = forms.CharField( 18 label="密碼", 19 required=True, 20 error_messages={ 21 "required": "密碼不能爲空", 22 }, 23 widget=forms.widgets.PasswordInput(render_value=True) 24 ) 25 re_userpwd = forms.CharField( 26 label="確認密碼", 27 required=True, 28 error_messages={ 29 "required": "密碼不能爲空", 30 }, 31 widget=forms.widgets.PasswordInput(render_value=True) 32 ) 33 34 # 校驗時會調用 35 def clean(self): 36 data = self.cleaned_data 37 userpwd = data.get('userpwd') 38 re_userpwd = data.get('re_userpwd') 39 if userpwd != re_userpwd: 40 self.add_error('re_userpwd', '兩次輸入的密碼必須一致') 41 return data
指定某個字段是必需的。django
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", required=True ) pwd = forms.CharField(min_length=6, label="密碼")
label參數用來指定頁面中字段的標題,若是不指定,Field經過將字段名的全部下劃線轉換爲空格和第一個字母的大寫生成默認label。後端
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", ) pwd = forms.CharField(min_length=6, label="密碼")
給label指定後綴。api
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", label_suffix=':' ) pwd = forms.CharField(min_length=6, label="密碼")
給字段指定默認(初始)值。若要指定動態初始數據,請參見Form.initial
參數。服務器
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三" # 設置默認值 ) pwd = forms.CharField(min_length=6, label="密碼")
widget參數用於使用指定的Widget類來呈現Field(例如數字)。(小部件的更多信息)app
help_text參數容許爲Field指定描述性文本。若是提供help_text參數,它將顯示在Field後。ide
from django import forms class LoginForm(forms.Form): username = forms.CharField( min_length=8, max_length=32, label="用戶名", help_text='32 characters max.' ) pwd = forms.CharField(min_length=6, label="密碼")
用來重寫錯誤信息。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三", error_messages={ "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" } ) pwd = forms.CharField(min_length=6, label="密碼")
validators參數容許爲該字段提供驗證函數的列表。(想了解更多信息見驗證器文檔)。
# 限定偶數驗證器 from django import forms from django.core.exceptions import ValidationError def validate_even(value): print(value) if value % 2 != 0: raise ValidationError( '%(value)s is not an even number', params={'value': value}, ) class SimpleForm(forms.Form): even_field = forms.IntegerField(validators=[validate_even])
from django import forms from django.core.validators import RegexValidator class SimpleForm(forms.Form): phone_number = forms.CharField( validators=[RegexValidator(r'^[0-9]+$', '請輸入數字'), RegexValidator(r'^159[0-9]{8}$', '數字必須以159開頭且11位')], )
localize參數支持表單數據輸入和呈現輸出的本地化。(想了解更多信息見格式本地化文檔)。
該參數爲布爾類型,設置爲True,則禁用表單字段,使其不能被用戶編輯。即便用戶篡改了提交給服務器的字段的值,它也會被忽略。
forms庫附帶了一組常見驗證需求的Field類。本節記錄一部份內置字段。想了解更多可參考Django官方文檔。
對於每一個字段,描述了不指定widget時使用的默認小部件類。還描述了在表單中提供空值時後臺所對應的值(請參閱required瞭解這意味着什麼)。
False
True或False
值是否爲True(若是字段具備required=True)
例如,選中複選框。
required
由於Field
類默認required=True。若是要在窗體中包含一個布爾值,能夠選擇True
或False
(例如選中或未選中複選框),必須記住傳入required=False
建立BooleanField
.
字符串。
max_length
或min_length
,若是提供的話。不然,全部輸入都是有效的。
required
, max_length
, min_length
若是提供了這些參數,則確保字符串最多或至少爲給定長度。
若是True(默認),該值將被去掉前導和尾隨空格。
ChoiceField
''
(空字符串)
字符串。
給定值是否存在於選項列表中。
required
, invalid_choice
接收一個元組(列表)序列或返回該序列的函數句柄。
1 def choiceList(): 2 return [(1, '張三'), (2, '李四')] 3 4 5 class TestForm(forms.Form): 6 f1 = forms.ChoiceField(choices=choiceList) 7 f2 = forms.ChoiceField(choices=[(1, '張三'), (2, '李四')])
TypedChoiceField
由coerce參數決定。
給定值是否存在於選項列表中,並可強制執行。
required
, invalid_choice
coerce
該參數接受一個函數,這個函數接受一個參數並返回一個的值做爲cleaned_data中的值,而這個參數正是用戶選擇的值。返回值能夠是int
, float
, bool
以及其餘類型。
1 from django.shortcuts import render, HttpResponse 2 from django import forms 3 4 5 def choiceList(): 6 return [(1, '張三'), (2, '李四')] 7 8 9 def coerceFunc(value): 10 return ['選擇的是{}'.format(tuple[1]) for tuple in choiceList() if tuple[0] == int(value)][0] 11 12 13 class TestForm(forms.Form): 14 f1 = forms.TypedChoiceField(choices=choiceList, coerce=coerceFunc) 15 16 17 def test(request): 18 form_obj = TestForm() 19 if request.method == 'POST': 20 form_obj = TestForm(request.POST) 21 if form_obj.is_valid(): 22 print(form_obj.cleaned_data.get('f1')) # 選擇的是張三 23 24 return render(request, 'test.html', {'form_obj': form_obj})
None
datetime.date
給定值是否爲datetime.date
, datetime.datetime
或以特定日期格式化的字符串。
required
, invalid
用於嘗試將字符串轉換爲有效的格式的列表。datetime.date
對象。
若是沒有input_formats
參數,默認輸入格式以下:
['%Y-%m-%d', # '2006-10-25' '%m/%d/%Y', # '10/25/2006' '%m/%d/%y'] # '10/25/06'
此外,若是指定USE_L10N=False
在您的設置中,默認輸入格式還將包括下列內容:
['%b %d %Y', # 'Oct 25 2006' '%b %d, %Y', # 'Oct 25, 2006' '%d %b %Y', # '25 Oct 2006' '%d %b, %Y', # '25 Oct, 2006' '%B %d %Y', # 'October 25 2006' '%B %d, %Y', # 'October 25, 2006' '%d %B %Y', # '25 October 2006' '%d %B, %Y'] # '25 October, 2006'
另見格式本地化。
None
datetime.datetime
給定值是否爲datetime.datetime
, datetime.date
或以特定日期時間格式化的字符串。
required
,invalid
用於嘗試將字符串轉換爲datetime.datetime
對象的有效的格式的列表。。
若是沒有input_formats
參數,默認輸入格式以下:
['%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59' '%Y-%m-%d %H:%M', # '2006-10-25 14:30' '%Y-%m-%d', # '2006-10-25' '%m/%d/%Y %H:%M:%S', # '10/25/2006 14:30:59' '%m/%d/%Y %H:%M', # '10/25/2006 14:30' '%m/%d/%Y', # '10/25/2006' '%m/%d/%y %H:%M:%S', # '10/25/06 14:30:59' '%m/%d/%y %H:%M', # '10/25/06 14:30' '%m/%d/%y'] # '10/25/06'
另見格式本地化.
DecimalField
localize=
False時爲
NumberInput,localize=True時爲
TextInput。
None
decimal
給定值是否爲十進制格式,前導和尾隨空格會被忽略。
required
,invalid
,max_value
,min_value
,max_digits
,max_decimal_places
,max_whole_digits
max_value和min_value錯誤消息可能包含%(limit_value)s,它將被適當的限制所取代。相似地,max_digits, max_decimal_places和max_whole_digits錯誤消息可能包含%(max)s.
控制字段中容許值的範圍(最小值和最大值)。
值中容許的最大數字數(小數點以前的數字加上小數點以後的數字,並去掉前導零)。
容許的最大小數位數。
DurationField
None
給定值是否爲可轉換爲timedelta。
required
, invalid
接收任何可經過parse_duration()轉換的值。
''
(空字符串)
字符串
使用一箇中等複雜的正則表達式驗證給定的值是不是一個有效的電子郵件地址。
required
, invalid
有兩個用於驗證的可選參數,max_length和min_length。若是提供了這些參數,則確保字符串最多或至少爲給定長度。
None
UploadedFile
對象,該對象將文件內容和文件名包裝到單個對象中。
非空文件數據是否已綁定到控件。
required
, invalid
, missing
, empty
, max_length
有兩個用於驗證的可選參數,max_length和allow_empty_file。若是提供,則確保文件名最多爲給定長度,即便文件內容爲空,驗證也將成功。
想了解更多關於UploadedFile
對象,請參閱文件上載文檔。
當你在form中使用FileField時
,還必須記住將文件數據綁定到窗體.
max_length
是指文件名的長度。在該鍵的錯誤消息中,%(max)d
將被替換爲最大文件名長度和%(length)d
將被替換爲當前文件名長度。
None
字符串
所選項是否存在於選項列表中。
required
, invalid_choice
其內容所在目錄的絕對路徑。這個目錄必須存在。
若是是False,
直接將path下內容提供做爲選擇。若是True
,目錄將被遞歸地將全部的後代做爲選擇列出。
正則表達式模式,只有具備與此表達式匹配的名稱的文件才容許做爲選擇。
可選的。True
或False
。默認值是True
。指定是否包括指定位置中的文件。若是這個是False那麼allow_folders
必定是True。
可選的。True
或False
。默認值是False
。指定是否應包括指定位置中的文件夾。若是這個是False那麼allow_files
必定是True
.
None
UploadedFile
對象,該對象將文件內容和文件名包裝到單個對象中。
文件數據是否已綁定到表單,而且該文件是否具備由Pillow可解析的圖像格式。
required
, invalid
, missing
, empty
, invalid_image
要使用ImageField,要求已安裝的Pillow支持該格式。
若是在上傳的時候遇到corrupt image error,這一般表示Pillow不能解析該格式。要解決這個問題,請安裝適當的庫並從新安裝Pillow。
當在表單上使用ImageField時
,還必須記住將文件數據綁定到窗體。
在清理和驗證字段後,UploadedFile
對象將有一個額外image屬性,它包含Pillow的image實例,用於檢查文件是否爲有效圖像。還有,UploadedFile.content_type
將被更新爲圖像的內容類型,前提是Pillow能夠解析它,不然它將被設置爲None
.
GenericIPAddressField
''
(空字符串)
字符串
給定值是否爲有效的IP地址。
required
, invalid
限制指定協議的有效輸入,默認值是both
,IPv4
或IPv6
。匹配是不區分大小寫的。
解包IPv 4映射地址,如::ffff:192.0.2.1
。若是啓用此選項,該地址將解壓縮到192.0.2.1
。默認值爲禁用。只能在protocol
設置爲'both'時使用。
.
[]
(空list)
字符串列表
給定值列表中的每一個值是否存在於選項列表中。
required
, invalid_choice
, invalid_list
invalid_choice錯誤信息可能包含%(value)s,它將被選定的選項替換。
相對ChoiceField
來講該參數在這裏是必選的。
empty_value
由coerce參數決定
給定值是否存在於選項列表中,並可強制執行。
required
, invalid_choice
invalid_choice錯誤信息可能包含%(value)s,它將被選定的選項替換。
None
False、True或None。
任何內容(即,它從不引起ValidationError
)。
''
(空字符串)
字符串。
給定值是否與某個正則表達式匹配。
required
, invalid
指定爲字符串類型正則表達式或編譯後的正則表達式對象。
默認爲False
。若是啓用,將在regex驗證以前去除先後空格。
''
(空字符串)
字符串。
給定的值只包含字母、數字、下劃線和連字符。
required
, invalid
指示字段除接受ASCII字母以外還接受Unicode字母的布爾值,默認爲False。
參數說明
None
datetime.time
給定值是否爲datetime.time
或以特定時間格式化的字符串。
required
, invalid
用於嘗試將字符串轉換爲datetime.time
對象的有效的格式的列表。
若是沒有input_formats參數,默認輸入格式以下:
'%H:%M:%S', # '14:30:59' '%H:%M', # '14:30'
''
(空字符串)
字符串
給定值是否爲有效URL。
required
, invalid
控制輸入長度範圍。
from django.db import models class UserInfo(models.Model): name =models.CharField(max_length=32) password = models.CharField(max_length=20) age = models.IntegerField() sex = models.IntegerField(choices=((1,'男'),(0,'女')))
from django import forms from app import models class UserForm(forms.ModelForm): class Meta: model = models.UserInfo fields = '__all__' labels = { "name": "用戶名", "sex": "性別", 'age':'年齡', 'password':'密碼' } widgets = { "password": forms.widgets.PasswordInput(attrs={"class": "c1"}), }
ModelForm類中Meta類下經常使用字段說明:
model = models.UserInfo # 對應的Model中的類 fields = "__all__" # 字段,若是是__all__,就是表示列出全部的字段,也能夠是一個須要渲染的字段名列表。 exclude = None # 排除的字段 labels = None # 提示信息 help_texts = None # 幫助提示信息 widgets = None # 自定義插件 error_messages = None # 自定義錯誤信息
from django import forms class CommentForm(forms.Form): comment = forms.CharField(widget=forms.Textarea)效果:
class SimpleForm(forms.Form): birth_year = forms.DateField(widget=forms.SelectDateWidget(years=('1980', '1981', '1982')))效果:
from django import forms class SimpleForm(forms.Form): favorite_colors = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple, choices=( ('blue', 'Blue'), ('green', 'Green'), ('black', 'Black'), ) )效果:
from django import forms class SimpleForm(forms.Form): choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=(('1', 'First',), ('2', 'Second',)))效果:
from django import forms class SimpleForm(forms.Form): # CharField字段默認小部件就是TextInput,因此指定和不指定的效果是同樣的。 name = forms.CharField(widget=forms.TextInput())效果:
from django import forms class SimpleForm(forms.Form): hobby = forms.fields.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=3, widget=forms.widgets.Select() )效果:
from django import forms class SimpleForm(forms.Form): hobby = forms.fields.MultipleChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=[1, 3], widget=forms.widgets.SelectMultiple() )效果:
單選勾選框。
from django import forms class SimpleForm(forms.Form): keep = forms.fields.ChoiceField( label="是否記住密碼", initial="checked", widget=forms.widgets.CheckboxInput() )效果:
能夠經過attrs來給小部件指定展現時的屬性:
from django import forms name = forms.TextInput(attrs={'size': 10, 'title': 'Your name'}) name.render('name', 'A name') '<input title="Your name" type="text" name="name" value="A name" size="10" />'
可經過重寫form類的__init__方法實現。
class LoginForm(forms.Form): username = forms.CharField( min_length=8, label="用戶名", initial="張三", error_messages={ "required": "不能爲空", "invalid": "格式錯誤", "min_length": "用戶名最短8位" } ... def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) for field in iter(self.fields): self.fields[field].widget.attrs.update({ 'class': 'form-control' })