form组件
我們在某個(gè)網(wǎng)站注冊賬號的時(shí)候,總會遇到下面的情況:
限定用戶名的長度最少8位
用戶輸入的密碼最短8位,最長28位
還有用戶輸入的手機(jī)號或者郵箱驗(yàn)證等
這些情況都可以由Django的form來實(shí)現(xiàn)。
Django中的form表單的定義
Django的表單系統(tǒng)中,所有的表單都繼承自django.forms.Form類
基于Django的表單系統(tǒng),主要分兩類:
基于django.forms.Form:所有表單類的父類
基于django.forms.ModelForm:與模型類綁定的Form
Django的form的使用
先在views.py中自定義一個(gè)MyForm類
class MyForm(forms.Form):
user=forms.CharField()
age=forms.IntegerField()
email=forms.EmailField()
然后再定義一個(gè)reg的視圖函數(shù)
def reg(request):
form_obj=MyForm() # 實(shí)例化一個(gè)MyForm類
return render(request,"reg.html",{"form_obj":form_obj})
再生成一個(gè)reg的網(wǎng)頁,配置好路由表,reg.html的內(nèi)容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>{{ error_message }}</h4>
<form action="/reg/" method="post">
{% csrf_token %}
{{ form_obj.as_p }}
</form>
</body>
</html>
啟動程序,用瀏覽器打開http://127.0.0.1:8000/reg/后,可以看到瀏覽器上的頁面如下:
在MyForm類中定義了用戶名user,年齡age和郵箱email三個(gè)注冊項(xiàng),而在前端頁面上就顯示了三個(gè)標(biāo)簽。
所以可以知道這三個(gè)標(biāo)簽是由form_obj這個(gè)對象創(chuàng)建出來的。
** 在前端頁面提示用戶輸入信息時(shí)都是英文格式,想變成漢語格式的應(yīng)該怎么辦呢??? **
把上面定義的MyForm類修改
class MyForm(forms.Form):
user=forms.CharField(label="用戶")
age=forms.IntegerField(label="年齡")
email=forms.EmailField(label="郵箱")
刷新網(wǎng)頁,顯示頁面如下
查看網(wǎng)頁的源碼,每個(gè)標(biāo)簽由一個(gè)label標(biāo)簽和input標(biāo)簽組成,而且每個(gè)標(biāo)簽都被一個(gè)p標(biāo)簽包圍,
在前端頁面上只寫了form_obj.as_p,所以所有標(biāo)簽都是由Django的模板語言按照form表單的語法渲染出來的。
這種方式生成的代碼封裝性很好,但是可拓展性太差了。
** 如果我想在p標(biāo)簽里面再添加一些別的裝飾呢,這又怎么辦呢??? **
修改前端頁面的代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>{{ error_message }}</h4>
<form action="/reg/" method="post">
{% csrf_token %}
<p>姓名:{{ form_obj.user }}</p>
<p>年齡:{{ form_obj.age }}</p>
<p>郵箱:{{ form_obj.email }}</p>
<input type="submit">
</form>
</body>
</html>
在這里,我們就生成一個(gè)姓名,年齡和郵箱的文本,其余的交由form來渲染,渲染結(jié)果如下:
再來看網(wǎng)頁的源碼
原來的label標(biāo)簽已經(jīng)沒有了,取而代之的是自定義的文本,而且只剩下一個(gè)input標(biāo)簽了。
而且可以看到每個(gè)標(biāo)簽的type屬性不一樣,跟MyForm類里定義的字段類型是一樣的。
在MyForm類中定義的用戶名user字段的類型是CharField類型,渲染后變成了text類型
在MyForm類中定義的用戶名age字段的類型是IntegerField類型,渲染后變成了number類型
在MyForm類中定義的用戶名email字的類型是EmailField類型,渲染后變成了email類型
而且其name屬性和id屬性的值都跟MyForm類中定義的字段是一樣的。
看完了源碼,現(xiàn)在什么信息都不輸入就點(diǎn)擊提交按鈕會發(fā)生什么呢??
瀏覽器提示信息告訴我們用戶信息這一欄不能為空。
在用戶信息欄里輸入信息,再次點(diǎn)擊提交按鈕,又會在年齡欄中提示不能為空。
在這里如果我們向年齡信息欄中輸入的是字母或特殊符號,也會輸入不上,而只能輸入數(shù)字。
因?yàn)樵贛yForm類中定義字段時(shí)使用了Integer類型。
同樣的,在郵箱字段里也有同樣的輸入要求。
** 對用戶輸入的用戶名和密碼的長度進(jìn)行設(shè)定 **
修改MyForm類
class MyForm(forms.Form):
user = forms.CharField(label="用戶",min_length=5,max_length=12)
age = forms.IntegerField(label="年齡")
email = forms.EmailField(label="郵箱")
刷新瀏覽器,看會發(fā)生什么情況??
提示必須輸入的信息的長度不能小于5。
修改reg視圖函數(shù)
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
print(form_post.is_valid())
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj})
打開IE瀏覽器,填寫如下信息,然后提交
在服務(wù)端后臺打印的信息如下
False
可以看到is.valid()方法返回的是一個(gè)布爾值。
按照正確的要求填寫并提交信息后,后臺才會打印True。
可以知道,Django的form到底有多少層校驗(yàn)取決于views.py的類中每個(gè)字段的類型及參數(shù)的個(gè)數(shù).
如果用戶輸入的信息符合設(shè)定的要求,那么接下來就必須把用戶填寫的注冊信息添加到數(shù)據(jù)庫中。
先修改視圖函數(shù),看Django的form把用戶輸入的數(shù)據(jù)轉(zhuǎn)換成什么樣子的了。
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
if form_post.is_valid():
print("data:",form_post.cleaned_data)
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj})
刷新瀏覽器,重新輸入注冊信息,打印如下
data: {'user': 'aaaaaa', 'age': 100, 'email': 'bbbb@qq.com'}
可以看到Django的form把用戶輸入的信息封裝成一個(gè)字典了。
此時(shí)添加數(shù)據(jù)庫就可以使用關(guān)鍵字參數(shù)了。
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
if form_post.is_valid():
print("data:",form_post.cleaned_data)
models.UserInfo.objects.create_user(**form_post)
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj})
進(jìn)行校驗(yàn)的時(shí)候,如果出現(xiàn)錯(cuò)誤,就應(yīng)該把錯(cuò)誤信息返回,該怎么做呢??
先打印下錯(cuò)誤信息及錯(cuò)誤信息的類型
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
if form_post.is_valid():
print("data:",form_post.cleaned_data)
models.UserInfo.objects.create_ue(**form_post)
else:
print(form_post.errors)
print(type(form_post.errors))
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj})
打印信息如下:
<ul class="errorlist">
<li>user<ul class="errorlist"><li>This field is required.</li></ul></li>
<li>age<ul class="errorlist"><li>This field is required.</li></ul></li>
<li>email<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
<class 'django.forms.utils.ErrorDict'>
可以看到,返回的錯(cuò)誤信息是一個(gè)字典。
既然是一個(gè)字典類型,那么就可以取出其中的值。
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
if form_post.is_valid():
print("data:",form_post.cleaned_data)
models.UserInfo.objects.create_ue(**form_post)
else:
print("user_errors:",form_post.errors["user"])
print("age_errors:",form_post.errors["age"])
print("email_errors:",form_post.errors["email"])
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj})
打印結(jié)果如下:
user_errors: <ul class="errorlist"><li>This field is required.</li></ul>
age_errors: <ul class="errorlist"><li>This field is required.</li></ul>
email_errors: <ul class="errorlist"><li>This field is required.</li></ul>
返回的信息是一個(gè)<ul><li>標(biāo)簽,其錯(cuò)誤信息的內(nèi)容為"This field is required."。
修改views.py文件
def reg(request):
if request.method=='POST':
form_post=MyForm(request.POST)
if form_post.is_valid():
print("data:",form_post.cleaned_data)
models.UserInfo.objects.create_user(**form_post)
else:
errors_obj=form_post.errors
print("user_errors:",errors_obj["user"])
print("age_errors:",errors_obj["age"])
print("email_errors:",errors_obj["email"])
form_obj=MyForm()
return render(request,"reg.html",{"form_obj":form_obj,"errors_obj":errors_obj})
修改前端網(wǎng)頁reg.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>{{ error_message }}</h4>
<form action="/reg/" method="post">
{% csrf_token %}
<p>姓名:{{ form_obj.user }}<span>{{ errors_obj.user.0 }}</span></p>
<p>年齡:{{ form_obj.age }}<span>{{ errors_obj.age.0 }}</span></p>
<p>郵箱:{{ form_obj.email }}<span>{{ errors_obj.email.0 }}</span></p>
<input type="submit">
</form>
</body>
</html>
這樣就可以把錯(cuò)誤信息渲染到前端網(wǎng)頁了,如下所示,正常打開網(wǎng)頁時(shí),不會顯示錯(cuò)誤信息
當(dāng)輸入的信息不符合定義的要求時(shí),就顯在網(wǎng)頁上顯示錯(cuò)誤信息了
如果想自定義在前端網(wǎng)頁上顯示的錯(cuò)誤信息,該怎么辦呢?
修改MyForm類,如下
class MyForm(forms.Form):
user = forms.CharField(label="用戶",min_length=5,max_length=12,error_messages={"required":"用戶名必填"})
age = forms.IntegerField(label="年齡",error_messages={"required":"年齡必填"})
email = forms.EmailField(label="郵箱",error_messages={"required":"郵箱必填"})
此時(shí),再次刷新瀏覽器,點(diǎn)擊提交按鈕,顯示如下
總結(jié)
- 上一篇: QQ抓图功能的提取(dll使用示例)
- 下一篇: TransCoder代码详解(二):ML