Form表單的功能 自動生成HTML表單元素 檢查表單數據的合法性 如果驗證錯誤,重新顯示表單(數據不會重置) 數據類型轉換(字元類型的數據轉換成相應的Python類型) Form相關的對象包括 Widget:用來渲染成HTML元素的工具,如:forms.Textarea對應HTML中的<texta ...
Form表單的功能
- 自動生成HTML表單元素
- 檢查表單數據的合法性
- 如果驗證錯誤,重新顯示表單(數據不會重置)
- 數據類型轉換(字元類型的數據轉換成相應的Python類型)
Form相關的對象包括
- Widget:用來渲染成HTML元素的工具,如:forms.Textarea對應HTML中的<textarea>標簽
- Field:Form對象中的一個欄位,如:EmailField表示email欄位,如果這個欄位不是有效的email格式,就會產生錯誤。
- Form:一系列Field對象的集合,負責驗證和顯示HTML元素
- Form Media:用來渲染表單的CSS和JavaScript資源。
Form案例驗證
前端:form表單
後臺:創建form類,當請求到來時,先匹配,匹配出正確和錯誤信息。
案例一:
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 # Create your views here. 6 def form1(request): 7 if request.method=="POST": #這裡POST一定要大寫 8 #獲取請求內容,做驗證 9 f = forms.UserMessage(request.POST) #request.POST:將接收到的數據通過forms.UserMessage驗證 10 if f.is_valid(): #驗證請求的內容和forms.UserMessage裡面的是否驗證通過。通過是True,否則False。 11 print(f.cleaned_data) #cleaned_data類型是字典,裡面是提交成功後的信息 12 else: #錯誤信息包含是否為空,或者符合正則表達式的規則 13 print(type(f.errors),f.errors) #errors類型是ErrorDict,裡面是ul,li標簽 14 return render(request,"app02/form1.html",{"error":f.errors}) 15 return render(request,"app02/form1.html")
form1.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>基礎版</title> 6 </head> 7 <body> 8 <!--{#{{ error }}接收後臺返回的錯誤信息封裝在ul,li標簽裡面:#} --> 9 {{ error }} 10 <form action="/app02/form1/" method="POST"> 11 <div> 12 用戶名:<input type="text" name="username" /> 13 </div> 14 <div> 15 密 碼:<input type="text" name="password" /> 16 </div> 17 <div> 18 <input type="submit" value="提交" /> 19 </div> 20 </form> 21 </body> 22 </html>
forms.py
#coding:UTF8 from django import forms from app02 import models class UserMessage(forms.Form): UserName = forms.CharField(max_length=100,label='用戶名') Password = forms.CharField(max_length=100,label='密碼')
訪問頁面:
沒有輸入內容後提交,通過模板語言展示了錯誤信息
form驗證時不用自定義錯誤信息就可以返回錯誤信息到前端以標簽方式展現。
.is_valid():返回True或者False
.cleaned_data:通過驗證後的數據
errors:
.error.get("user",None)error封裝所有的錯誤信息,如果沒有獲取到,預設為None。
.error.get["pwd"]直接獲取到ul、li。
如下:
(<class 'django.forms.utils.ErrorDict'>, {'UserName': [u'This field is required.'], 'Password': [u'This field is required.']})
案例二:
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 def form2(request): 6 if request.method == "POST": 7 f = forms.UserMessage(request.POST) 8 if f.is_valid(): 9 print(f.cleaned_data) 10 else: 11 return render(request,"app02/form2.html",{"error":f.errors,"form":f}) 12 else: 13 # 如果不是post提交數據,就不傳參數創建對象,並將對象返回給前臺,直接生成input標簽,內容為空 14 f = forms.UserMessage() 15 return render(request,"app02/form2.html",{"form":f}) 16 return render(request,"app02/form2.html")
form2.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>進階版</title> 6 <style> 7 .input-group{ 8 position: relative; 9 padding: 20px; 10 width: 250px; 11 } 12 .input-group input{ 13 width: 200px; 14 display: inline-block; 15 } 16 </style> 17 </head> 18 <body> 19 <form action="/app02/form2/" method="POST"> 20 <div class="input-group">用戶名: 21 <!-- {#接收後臺傳過來的form對象,自動生成input標簽#}--> 22 {{ form.UserName }} 23 <!-- {#從後臺傳過來的error是字典,直接{{ error.UserName.0 }}呈現錯誤信息#} --> 24 <!-- {#如果後臺返回了錯誤信息,將錯誤信息放入span標簽,在頁面顯示,否則不顯示#}--> 25 {% if error.UserName.0 %} 26 <span>{{ error.UserName.0 }}</span> 27 {% endif %} 28 </div> 29 <div class="input-group">密碼: 30 {{ form.Password }} 31 {% if error.Password.0 %} 32 <span>{{ error.Password.0 }}</span> 33 {% endif %} 34 </div> 35 <div> 36 <input type="submit" value="提交" /> 37 </div> 38 </form> 39 </body> 40 </html>
forms.py
1 #coding:UTF8 2 from django import forms 3 from app02 import models 4 class UserMessage(forms.Form): 5 UserName = forms.CharField(max_length=100,label='用戶名') 6 Password = forms.CharField(max_length=100,label='密碼')
案例三:
models.py
1 #coding:Utf8 2 from __future__ import unicode_literals 3 4 from django.db import models 5 from django import forms 6 7 # Create your models here. 8 class Author(models.Model): 9 #作者 10 name = models.CharField(max_length=100) 11 age = models.IntegerField() 12 13 class BookType(models.Model): 14 #圖書類型 15 caption = models.CharField(max_length=64) 16 17 class Book(models.Model): 18 #圖書 19 name = models.CharField(max_length=64) 20 pages = models.IntegerField() 21 price = models.DecimalField(max_digits=10,decimal_places=2) 22 pubdate = models.DateField() 23 24 authors = models.ManyToManyField(Author) 25 book_type = models.ForeignKey(BookType)
views.py
1 #coding:utf8 2 from django.shortcuts import render,HttpResponseRedirect 3 from app02 import forms,models 4 5 def form3(request): 6 if request.method == "POST": 7 f = forms.Form3(request.POST) 8 if f.is_valid(): 9 print(f.cleaned_data) 10 else: 11 return render(request,"app02/form3.html",{"error":f.errors,"form":f}) 12 else: 13 # 如果不是post提交數據,就不傳參數創建對象,並將對象返回給前臺,直接生成input標簽,內容為空 14 f = forms.Form3() 15 return render(request,"app02/form3.html",{"form":f}) 16 return render(request,"app02/form3.html")
form3.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <style> 6 .input-group{ 7 position: relative; 8 padding: 20px; 9 width: 250px; 10 } 11 .input-group input{ 12 width: 200px; 13 display: inline-block; 14 } 15 .inline-group span{ 16 display: inline-block; 17 position: absolute; 18 height: 12px; 19 font-size: 8px; 20 border: 1px solid red; 21 background-color: coral; 22 color: white; 23 top: 41px; 24 left: 20px; 25 width: 202px; 26 } 27 </style> 28 <title>高級版</title> 29 </head> 30 <body> 31 <form action="/app02/form3/" method="POST"> 32 <div class="input-group"> 33 <!--{#接收後臺傳過來的form對象,自動生成input標簽#} --> 34 用戶名:{{ form.UserName }} 35 <!--{#從後臺傳過來的error是字典,直接{{ error.user.0 }}呈現錯誤信息#} --> 36 <!--{#如果後臺返回了錯誤信息,將錯誤信息放入span標簽,在頁面顯示,否則不顯示#} --> 37 {% if error.UserName.0 %} 38 <span>{{ error.UserNamer.0 }}</span> 39 {% endif %} 40 </div> 41 <div class="input-group"> 42 密碼:{{ form.Password }} 43 {% if error.Password.0 %} 44 <span>{{ error.Password.0 }}</span> 45 {% endif %} 46 </div> 47 <div class="input-group"> 48 郵箱:{{ form.Email }} 49 {% if error.Email.0 %} 50 <span>{{ error.Email.0 }}</span> 51 {% endif %} 52 </div> 53 <!-- <div class="input-group"> 54 詳細介紹:{{ form.Memo }} 55 {% if error.Memo.0 %} 56 <span>{{ error.Memo.0 }}</span> 57 {% endif %}--> 58 </div> 59 <div class="input-group"> 60 書籍類型:{{ form.book_type }} 61 {% if error.book_type.0 %} 62 <span>{{ error.book_type.0 }}</span> 63 {% endif %} 64 </div> 65 66 <div> 67 <input type="submit" value="提交" /> 68 </div> 69 </form> 70 </body> 71 </html>
forms.py
1 #coding:UTF8 2 from django import forms 3 from app02 import models 4 5 class Form3(forms.Form): 6 UserName = forms.CharField( 7 widget=forms.TextInput(attrs={'class': 'c1'}), 8 error_messages={'required': '用戶名不能為空'}, 9 ) 10 Password = forms.CharField(max_length=4, min_length=2,required=True) 11 Email = forms.EmailField(error_messages={'required': '郵箱不能為空', 'invalid': '郵箱格式錯誤'}) 12 13 #Memo = forms.CharField(required=False,widget=forms.Textarea()) 14 #直接寫數據 15 user_type_choice = ( 16 (0, '普通用戶'), 17 (1, '高級用戶'), 18 ) 19 #通過BookType表查詢信息,values_list拿到的是元組。id作為value顯示,caption作為text在頁面顯示 20 # user_type_choice = models.BookType.objects.values_list('id', 'caption') 21 book_type = forms.CharField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) 22 23 24 #寫上以下代碼就不用擔心資料庫添加了數據而不能及時獲取了 25 def __init__(self, *args, **kwargs): 26 #每次創建Form1對象時執行init方法 27 super(Form3, self).__init__(*args, **kwargs) 28 29 self.fields['book_type'] = forms.CharField( 30 widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id', 'caption'), 31 attrs={'class': "form-control"}))