表單介紹
HTML表單負(fù)責(zé)接收用戶的輸入,對輸入進(jìn)行合法格式判斷,并將數(shù)據(jù)發(fā)送到服務(wù)器。一個(gè)HTML表單必須指定兩樣?xùn)|西:發(fā)送數(shù)據(jù)的url地址,發(fā)送的HTTP方法(GET搞监、POST)水孩。
GET方法:將用戶數(shù)據(jù)以?<鍵1>=<值1>&<鍵2>=<值2>&...形式拼接到url后面,通常用于請求數(shù)據(jù)琐驴、網(wǎng)頁搜索的表單俘种。
POST方法:組合表單的數(shù)據(jù)并進(jìn)行編碼,然后打包發(fā)送到服務(wù)器绝淡,數(shù)據(jù)不會出現(xiàn)在url中宙刘,通常用于保密信息的發(fā)送、大量數(shù)據(jù)的表單牢酵、二進(jìn)制數(shù)據(jù)悬包。
在input標(biāo)簽中
#對于form表單也是一樣,如果前端不指定post方法馍乙,默認(rèn)使用get方法布近。
表單字段(常用)
CharField
渲染類型:TextInput
輸入空值的返回:empty_value設(shè)定的值
轉(zhuǎn)換為對象:Unicode對象
驗(yàn)證:min_length,max_length(如果設(shè)置過)
可用的錯(cuò)誤信息鍵:min_length丝格,max_length撑瞧,required
max_length:允許輸入的最大長度
min_length:允許輸入的最小長度
strip:默認(rèn)為True,表示去除前后的空格
empty_value:輸入為空時(shí)返回的值显蝌,默認(rèn)為空字符串
EmailField
渲染類型:EmailInput
輸入空值的返回:空字符串
轉(zhuǎn)換為對象:Unicode對象
驗(yàn)證:用正則表達(dá)式驗(yàn)證表單的值预伺,必須是合法郵件地址
可用的錯(cuò)誤信息鍵:required,invalid
max_length:允許輸入的最大長度
min_length:允許輸入的最小長度
表單字段的參數(shù)
error_messages
error_messages={‘key’: ‘value’}
自定義錯(cuò)誤提示信息,鍵是表單里同名的錯(cuò)誤類型字符串酬诀,值是自定義的提示信息字符串脏嚷。
其中的key包括:
required,無填寫內(nèi)容
invalid料滥,非法字符
maxlength然眼,超出長度上限
max_length
最大長度
min_length
最小長度
required
required=True/False
該字段必填/非必填。
當(dāng)為True時(shí)葵腹,<表單對象>.clean(‘‘)和<表單對象>.clean(None)返回ValidationError異常高每。
當(dāng)為False時(shí),<表單對象>.clean(‘‘)和<表單對象>.clean(None)返回None践宴。
?
label
label=’<顯示值>’
字段渲染成HTML代碼的提示詞鲸匿,默認(rèn)在后面加冒號。
如字段name = forms.CharField(label=’Your Name’)阻肩,顯示為HTML的
<label for=”id_name”>Your name:?</label>
<input id=”id_name”?type="text" name="name" required />
label_suffix
label_suffix=’<字符>’
自定義字符带欢,代替label生成顯示值后面的冒號。
initial
initial=’<值>’
為表單元素定義初始值烤惊,即標(biāo)簽中的value=乔煞,可傳入值和對象。
#?initial不會作為數(shù)據(jù)提交柒室,表單仍需要用戶填寫數(shù)據(jù)渡贾。
只能用initial傳遞初始值,如果在渲染表單的時(shí)候傳遞一個(gè)初始值字典雄右,會觸發(fā)表單的驗(yàn)證空骚,此時(shí)輸出的HTML頁面可能包含驗(yàn)證錯(cuò)誤。
widget
widget=<widget類>
指定渲染W(wǎng)idget時(shí)使用的widget類擂仍,即前端中的type類型囤屹。
可用attr參數(shù)傳入一個(gè)字典,對widget添加CSS樣式逢渔,如:
name = forms.CharField(widget=forms.TextInput(attrs={‘class’: ‘special’}) )
comment = forms.CharField(widget=forms.TextInput(attrs={‘size’: ‘40’}) )
help_text
help_text=’<文本>’
設(shè)定輔助性描述文本肋坚,相當(dāng)于HTML的默認(rèn)顯示值。
validators
validators=[ ]
傳入列表肃廓,包含對字段驗(yàn)證的函數(shù)冲簿,自定義驗(yàn)證方法的時(shí)候用。
localize
實(shí)現(xiàn)表單數(shù)據(jù)輸入的本地化亿昏。
disabled
disabled=True/False
設(shè)置對字段禁用/啟用編輯峦剔,禁用編輯后,即使非法篡改前端頁面的屬性向服務(wù)器提交角钩,該字段值也會被忽略吝沫。
表單API
綁定數(shù)據(jù)的表單能夠驗(yàn)證數(shù)據(jù)呻澜,然后生成HTML表單,未綁定的表單無法驗(yàn)證數(shù)據(jù)惨险,可生成HTML空表單羹幸。
創(chuàng)建空表單:f = <表單名>form()#創(chuàng)建表單類的實(shí)例
表單綁定數(shù)據(jù):data = {:}#字典鍵是表單的字段名,值是傳入的數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? ? f = <表單名>form(data)
? ? ? ? ? ? ? ? ? ? ? ? ??#傳入空字典將創(chuàng)建一個(gè)數(shù)據(jù)為空的已綁定表單
forms.Form實(shí)例的數(shù)據(jù)無法自讀辫愉,所以創(chuàng)建表單對象之后不可更改栅受。
表單的綁定
<表單對象>.is_bound
判斷表單是/否綁定了數(shù)據(jù),返回True/False恭朗。
表單的數(shù)據(jù)錯(cuò)誤驗(yàn)證
<表單對象>.is_valid()
驗(yàn)證表單數(shù)據(jù)合法性屏镊,返回True/False。.is_valid()實(shí)際就是檢查<表單對象>.errors是否為空痰腮,如果errors列表為空而芥,就把所有數(shù)據(jù)儲存到<表單對象>.cleaned_data字典中。
<表單對象>.errors
包含所有錯(cuò)誤信息的字典類型膀值,鍵是表單字段名棍丐,值是由錯(cuò)誤信息組成的字符串形列表。
<表單對象>.errors.as_data()
返回錯(cuò)誤信息的字典形式沧踏,將字段映射到原始的ValidationError實(shí)例歌逢,如:
{'sender': [ValidationError(['Enter a valid email address.'])?],
'subject': [ValidationError(['This field is required.'])?]?}
<表單對象>.errors.as_json()
錯(cuò)誤信息字典的JSON序列化形式,如:
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]?}
<表單對象>.add_error(<字段名>, <錯(cuò)誤信息>)
向表單的指定字段添加錯(cuò)誤信息翘狱。
<表單對象>.has_error(<字段>, code=xxx)
判斷某個(gè)字段是/否有指定的xxx錯(cuò)誤秘案,返回True/False。當(dāng)code=None時(shí)盒蟆,該字段有任何錯(cuò)誤都返回True。
<表單對象>.non_field_errors()
返回<表單對象>.errors中不是與特定字段關(guān)聯(lián)的錯(cuò)誤师骗。
?
表單的cleaned_data數(shù)據(jù)
①如果數(shù)據(jù)驗(yàn)證通過历等,把所有數(shù)據(jù)儲存到<表單對象>.cleaned_data字典中;如果數(shù)據(jù)驗(yàn)證不通過辟癌,只把合法的數(shù)據(jù)存到<表單對象>.cleaned_data字典中寒屯。
②cleaned_data只包含F(xiàn)orm類中的字段,如果傳遞額外數(shù)據(jù)黍少,將不被儲存寡夹。
③傳遞的數(shù)據(jù)不包含F(xiàn)orm類中的某字段,cleaned_data中依然包含該鍵值對厂置,顯示為空值菩掏。
表單的數(shù)據(jù)更改驗(yàn)證
<表單對象>.has_changed()
檢查表單數(shù)據(jù)是否從初始值發(fā)生改變,有改變返回True昵济,無改變返回False智绸,如:
data = <字典>
f = ContactForm(request.POST, initial=data) ?????#?POST和data內(nèi)容不一樣
f.has_changed()
<表單對象>.changed_data
返回表單中有數(shù)據(jù)變化的字段的列表野揪,如:
f = ContactForm(request.POST, initial=data) ?????#?POST和data內(nèi)容不一樣
print(“, “.join(f.changed_data) )
表單的HTML生成
form類不包含<form></form>標(biāo)簽和<input type=”submit”>提交按鈕,為方便開發(fā)人員自行編寫控制表單動作和CSS瞧栗,JS及如bootstrap框架的嵌入斯稳。
生成HTML標(biāo)簽的就是表單字段名,每個(gè)字段類型都由一個(gè)默認(rèn)的HTML標(biāo)簽展示迹恐,可用widget參數(shù)指定生成的類型挣惰。
表單自動為每個(gè)input元素設(shè)置一個(gè),用于的for參數(shù)殴边。
{{ form.as_p }}
將每個(gè)字段渲染成標(biāo)簽憎茂。
{{ form.as_ul }}
將每個(gè)字段渲染成
標(biāo)簽(無序),
{{ form.as_table }}
將表單的每個(gè)字段渲染成標(biāo)簽唇辨,標(biāo)簽需自己指定。
表單字段在前端的屬性
{{ field.value }} ?? ?? 當(dāng)前字段的值能耻,比如一個(gè)Email字段的值:someone@example.com
{{ field.errors }} ? ?? 包含錯(cuò)誤信息的元素
{{ field.label }} ?? 字段的label信息
{{ field.id_for_label }} 自定義字段標(biāo)簽的id
{{ field.html_name }} 指定字段生成的input標(biāo)簽中name屬性的值
{{ field.help_text }} 字段的幫助信息
{{ field.is_hidden }} 用于判斷當(dāng)前字段是否為隱藏的字段赏枚,隱藏則返回True
{{ field.field }} ? ?? 返回字段的參數(shù)列表,例如{{ char_field.field.max_length }}
表單錯(cuò)誤信息的CSS樣式
class <表單名>FORM(forms.Form):
????error_css_class = ‘error’
????required_css_class = ‘required’
? ??#其它表單字段...
以后這個(gè)表單渲染HTML時(shí)將自動為error行和required行添加對應(yīng)的CSS樣式晓猛。
表單上傳文件
沒看懂饿幅,略。戒职。栗恩。
模型表單ModelForm
基于model模型創(chuàng)建的表單,對模型的字段進(jìn)行重用洪燥,根據(jù)model字段的限制進(jìn)行表單驗(yàn)證磕秤。
驗(yàn)證后,ModelForm.save()實(shí)際就是調(diào)用Model.save()捧韵,直接保存到數(shù)據(jù)庫市咆。
from django.forms import ModelForm
from <應(yīng)用名>.models import <類>
class <類名>Form(ModelForm): ??????#繼承于ModelForm類
????class Meta: ????????????????????#設(shè)置元類Meta
????????model = <類> ??????????????#設(shè)置model屬性為某個(gè)模型類
????????fields = [<字段1>, <字段2>, ...] ?????#用field屬性傳入列表,指定類中的字段
????????fields = ‘__all__’????????????????????#也可用field屬性傳入類的全部字段
????????exclude = [<字段1>, <字段2>, ...] ????#用exclude屬性將排除的字段之外全部傳入
模型表單的保存
<模型表單對象>.save(commit=True) ??????#將form表單的內(nèi)容提交到數(shù)據(jù)庫并保存
如果沒有commit=True就只提交再来,不保存
指定數(shù)據(jù)對象
form = ModelForm(instance=<綁定的Model對象>)
此時(shí)可以直接form.save()將表單數(shù)據(jù)保存到數(shù)據(jù)表中蒙兰。
#如果不指定某個(gè)對象,save()時(shí)會在數(shù)據(jù)表中新增一行數(shù)據(jù)
模型字段對應(yīng)表單字段
Model???????????????????????????Form
AutoField ???????????????????????無對應(yīng)
BigAutoField ????????????????????無對應(yīng)
BigIntegerField ??????????????????IntegerField
CharField ???????????????????????相同芒篷,如果model設(shè)置null=True搜变,F(xiàn)orm將使用empty_value
CommaSeparatedIntegerField ?????CharField
ForeignKey ??????????????????????ModelChoiceField
ManyToManyField ????????????????ModelMultipleChoiceField
PositiveIntegerField ???????????????IntegerField
PositiveSmallIntegerField ??????????IntegerField
SmallIntegerField ?????????????????IntegerField
TextField ?????????????????????????CharField,屬性widget=forms.Textarea
模型字段設(shè)置blank=True屬性针炉,表單字段將設(shè)置required=False挠他,反之相反。
模型字段的verbose_name屬性會設(shè)為表單字段的label屬性篡帕,并將第一個(gè)字母大寫绩社。
模型字段設(shè)置editable=False屬性摔蓝,表單類中將不會出現(xiàn)該字段,因?yàn)樵撟侄尾豢删庉嫛?/p>
模型字段的help_text屬性即為表單字段的help_text屬性愉耙。
模型字段設(shè)置choices參數(shù)贮尉,表單字段的widget屬性將設(shè)置為Select,其選項(xiàng)和模型字段相同朴沿。表單選項(xiàng)中通常會包含一個(gè)空選項(xiàng)作為默認(rèn)猜谚,如果該字段必選,會強(qiáng)制用戶選擇一個(gè)選項(xiàng)赌渣;如果模型字段具有default參數(shù)魏铅,就不會在表單選項(xiàng)中添加空選項(xiàng)。
模型表單的驗(yàn)證
用.is_valid()方法或查詢.errors列表坚芜,也可以重寫模型表單的def clean()方法進(jìn)行額外的驗(yàn)證览芳,如:
class <類名>Form(ModelForm):
????class meta:
? ??????#?...
def clean_<函數(shù)名>(self):
? ??#驗(yàn)證self.cleaned_data字典的數(shù)據(jù)...
????return <數(shù)據(jù)>
自定義ModelForm字段
使用元類Meta的widgets屬性:
class <類名>Form(ModelForm):
????class Meta:
????????model = <類>
????????fields = [‘<字段1>’, ...]
????????widgets = { ???????????????????????#傳入字典,鍵是模型字段名鸿竖,值是自定義的內(nèi)容
????????????‘<字段1>’:Textarea(attrs={‘cols’:80, ‘rows’:20} ),
????????????...
????????}
ModelForm字段的本地化
使用Meta類的localized_fields屬性沧竟,傳入一個(gè)元組,指定本地化的字段:
class <類名>Form(ModelForm):
class meta:
????model = <類>
????localized_fields = (‘<字段1>’, ...) ??????#傳入’__all__’表示將類中的所有字段本地化
表單示例
①在forms.py中:
from django import forms
class <表單名>Form(forms.Form): ????#所有表單繼承于forms.Form類
????sender = forms.EmailField()
????name = forms.CharField(label=’Your Name’, max_length=100)
? ??#一個(gè)字段代表中的一個(gè)元素缚忧,字段負(fù)責(zé)驗(yàn)證和轉(zhuǎn)換數(shù)據(jù)
? ??#?label用于設(shè)置說明標(biāo)簽悟泵,這里的max_length同時(shí)限制前端和后端的輸入長度
②在views.py中:
from .forms import <表單名>Form
def get_name(request):
????if request.method == ’POST’: ?????????#對于POST方法發(fā)送數(shù)據(jù),接收數(shù)據(jù)并驗(yàn)證闪水、處理
????a_form = <表單名>Form(request.POST)
? ??#用request.POST字典構(gòu)造forms.Form類實(shí)例糕非,將所有數(shù)據(jù)加載到表單中
????????if a_form.is_valid():
? ??????????#處理表單數(shù)據(jù)...
????????????return HttpResponseRedirect(‘/xxx/’) ???#處理成功,重定向到一個(gè)新url
????if request.method == ’GET’: ????????????????#對于GET方法請求數(shù)據(jù)球榆,返回空表單到模板
????????a_form = <表單名>Form()
????return render(request, ‘xxx.html’, {‘form’: a_form}
#處理不成功時(shí)朽肥,給用戶返回這個(gè)模板。如果數(shù)據(jù)不合法持钉,邏輯會在if a_form.is_valid()處斷開衡招,
此時(shí)的a_form是包含原數(shù)據(jù)的表單,方便用戶修改
③在templates中:
<form action="/xxx/" method="post">??????????#寫標(biāo)簽
????{% csrf_token %}
????{{ form }}?????????????????????????????????#表單模型生成的form表單元素
????<input type="submit" value="Submit" />??????#寫提交按鈕
</form>
{{ form.<字段名> }} ?????????????獲取表單的字段內(nèi)容右钾,用于手動渲染表單
{{ form.<字段名>.label_tag }} ?????生成<label>標(biāo)簽蚁吝,用于手動渲染表單
{{ form.hidden_fields }} ??????????表單中的不可見字段的集合
{{ form.visible_fields }} ???????????表單中的可見字段的集合
表單模板的重用
將表單模板保存為一個(gè)獨(dú)立HTML文件旱爆,然后用{% include %}引用:
{% include ‘xxxform.html’?%}
{% for field in form %}
? ??#處理字段...
{% endfor %}
用with參數(shù)給表單取別名舀射,防止名稱沖突:
{% include ‘xxxform.html’?with form=<別名> %}
{% for field in <別名> %}
? ??#處理字段...
{% endfor %}