Django中的form表單
我們在某個網站注冊賬號的時候,總會遇到下面的情況:
限定用戶名的長度最少8位
用戶輸入的密碼最短8位,最長28位
還有用戶輸入的手機號或者郵箱驗證等
這些情況都可以由Django的form來實作,
一、Django中的form表單的定義
Django的表單系統中,所有的表單都繼承自django.forms.Form類
基于Django的表單系統,主要分兩類:
- 基于django.forms.Form:所有表單類的父類
- 基于django.forms.ModelForm:與模型類系結的Form
二、Django的form的使用
先在views.py中自定義一個MyForm類
class MyForm(forms.Form):
user=forms.CharField()
age=forms.IntegerField()
email=forms.EmailField()
然后再定義一個reg的視圖函式
def reg(request):
form_obj=MyForm() # 實體化一個MyForm類
return render(request,"reg.html",{"form_obj":form_obj})
再生成一個reg的網頁,配置好路由表,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 %}
{{ form_obj.as_p }}
</form>
</body>
</html>
啟動程式,用瀏覽器打開http://127.0.0.1:8000/reg/后,可以看到瀏覽器上的頁面如下:

在MyForm類中定義了用戶名user,年齡age和郵箱email三個注冊項,而在前端頁面上就顯示了三個標簽,
所以可以知道這三個標簽是由form_obj這個物件創建出來的,
在前端頁面提示用戶輸入資訊時都是英文格式,想變成漢語格式的應該怎么辦呢???
把上面定義的MyForm類修改
class MyForm(forms.Form):
user=forms.CharField(label="用戶")
age=forms.IntegerField(label="年齡")
email=forms.EmailField(label="郵箱")
重繪網頁,顯示頁面如下

查看網頁的原始碼,每個標簽由一個label標簽和input標簽組成,而且每個標簽都被一個p標簽包圍,

在前端頁面上只寫了form_obj.as_p,所以所有標簽都是由Django的模板語言按照form表單的語法渲染出來的,
這種方式生成的代碼封裝性很好,但是可拓展性太差了,
如果我想在p標簽里面再添加一些別的裝飾呢,這又怎么辦呢???
修改前端頁面的代碼
<!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>
在這里,我們就生成一個姓名,年齡和郵箱的文本,其余的交由form來渲染,渲染結果如下:

再來看網頁的原始碼

原來的label標簽已經沒有了,取而代之的是自定義的文本,而且只剩下一個input標簽了,
而且可以看到每個標簽的type屬性不一樣,跟MyForm類里定義的欄位型別是一樣的,
在MyForm類中定義的用戶名user欄位的型別是CharField型別,渲染后變成了text型別
在MyForm類中定義的用戶名age欄位的型別是IntegerField型別,渲染后變成了number型別
在MyForm類中定義的用戶名email字的型別是EmailField型別,渲染后變成了email型別
而且其name屬性和id屬性的值都跟MyForm類中定義的欄位是一樣的,
看完了原始碼,現在什么資訊都不輸入就點擊提交按鈕會發生什么呢??

瀏覽器提示資訊告訴我們用戶資訊這一欄不能為空,
在用戶資訊欄里輸入資訊,再次點擊提交按鈕,又會在年齡欄中提示不能為空,
在這里如果我們向年齡資訊欄中輸入的是字母或特殊符號,也會輸入不上,而只能輸入數字,
因為在MyForm類中定義欄位時使用了Integer型別,
同樣的,在郵箱欄位里也有同樣的輸入要求,
對用戶輸入的用戶名和密碼的長度進行設定
修改MyForm類
class MyForm(forms.Form):
user = forms.CharField(label="用戶",min_length=5,max_length=12)
age = forms.IntegerField(label="年齡")
email = forms.EmailField(label="郵箱")
重繪瀏覽器,看會發生什么情況??

提示必須輸入的資訊的長度不能小于5,
修改reg視圖函式
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瀏覽器,填寫如下資訊,然后提交

在服務端后臺列印的資訊如下
False
可以看到is.valid()方法回傳的是一個布林值,
按照正確的要求填寫并提交資訊后,后臺才會列印True,
可以知道,Django的form到底有多少層校驗取決于views.py的類中每個欄位的型別及引數的個數.
如果用戶輸入的資訊符合設定的要求,那么接下來就必須把用戶填寫的注冊資訊添加到資料庫中,
先修改視圖函式,看Django的form把用戶輸入的資料轉換成什么樣子的了,
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': '[email protected]'}
可以看到Django的form把用戶輸入的資訊封裝成一個字典了,
此時添加資料庫就可以使用關鍵字引數了,
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})
進行校驗的時候,如果出現錯誤,就應該把錯誤資訊回傳,該怎么做呢??
先列印下錯誤資訊及錯誤資訊的型別
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 >
<li>user<ul ><li>This field is required.</li></ul></li>
<li>age<ul ><li>This field is required.</li></ul></li>
<li>email<ul ><li>This field is required.</li></ul></li></ul>
<class 'django.forms.utils.ErrorDict'>
可以看到,回傳的錯誤資訊是一個字典,
既然是一個字典型別,那么就可以取出其中的值,
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})
列印結果如下:
user_errors: <ul ><li>This field is required.</li></ul>
age_errors: <ul ><li>This field is required.</li></ul>
email_errors: <ul ><li>This field is required.</li></ul>
回傳的資訊是一個<ul><li>標簽,其錯誤資訊的內容為"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})
修改前端網頁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>
這樣就可以把錯誤資訊渲染到前端網頁了,如下所示,正常打開網頁時,不會顯示錯誤資訊

當輸入的資訊不符合定義的要求時,就顯在網頁上顯示錯誤資訊了

如果想自定義在前端網頁上顯示的錯誤資訊,該怎么辦呢?
修改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":"郵箱必填"})
此時,再次重繪瀏覽器,點擊提交按鈕,顯示如下

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/136646.html
標籤:Python
下一篇:Python 字串操作常用知識點
