第三百一十一節,Django框架,Form表單驗證
表單提交
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/css/tou.css"> </head> <body> <form action="/bugarticles/" method="post"> <div> <input type="text" name="user"/> </div> <div> <input type="text" name="pwd"/> </div> <div> <input type="submit" value="提交"/> </div> </form> </body> </html>
路由映射
urlpatterns = [ url(r'admin/', admin.site.urls), #路由映射admin數據庫管理 url(r'articles/', views.special) ]
邏輯處理
method屬性獲取用戶請求方式,post或者get
使用方式:請求對象.method
POST獲取用戶post請求方式的信息
使用方式:請求對象.POST
POST.get()獲取用戶POST請求方式的表單name名稱對應的值,參數是表單name名
from django.shortcuts import render from app1.models import * #導入數據庫操作模塊 #邏輯處理模塊 def special(request): #自定義參數接收用戶請求對象 if request.method == "POST": #判斷用戶請求如果是post方式 print(request.POST.get('user',None)) #接收用戶表單提交的name名稱對應的值 print(request.POST.get('pwd', None)) #接收用戶表單提交的name名稱對應的值 return render(request, 'app1/index.html', locals()) # 打開頁面
表單提交驗證,獲取數據與獲取錯誤信息
1、創建表單驗證模塊,必須繼承Django的表單驗證forms.Form類
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField() #接收邏輯處理時,創建yhbd類時傳進來的POST對象,里的表單name名對應的值進行驗證 pwd = forms.CharField() ##接收邏輯處理時,創建yhbd類時傳進來的POST對象,里的表單name名對應的值進行驗證
2、邏輯處理,創建表單驗證模塊里的驗證類,並將用戶請求的POST對象,傳入驗證類進行驗證,驗證后獲取驗證通過的提交信息,或者驗證沒通過的錯誤信息
如果出現錯誤,將錯誤信息對象以字典方式傳到html頁面
is_valid()返回驗證是否通過的布爾值
使用方式:驗證類.is_valid()
cleaned_data獲取驗證通過后的所有提交數據,返回字典
使用方式:驗證類.cleaned_data
errors獲取驗證錯誤信息,返回所有表單的錯誤信息對象
使用方法:驗證類.errors
from django.shortcuts import render from app1.models import * #導入數據庫操作模塊 from app1.biaodan import * #導入自定義表單驗證模塊 #邏輯處理模塊 def special(request): if request.method == 'GET': return render(request, 'app1/index.html', locals()) # 打開頁面 if request.method == "POST": # print(request.POST.get('user',None)) #接收用戶表單提交的name名稱對應的值 # print(request.POST.get('pwd', None)) #接收用戶表單提交的name名稱對應的值 f = yhbd(request.POST) #創建驗證表單類,將用戶請求POST對象傳進表單驗證類進行驗證 # ret = f.is_valid() #返回驗證是否通過 # print(ret) #返回布爾值 if f.is_valid(): #判斷驗證如果通過 print(f.cleaned_data) #獲取到用戶提交信息,字典方式 else: #如果沒通過 print(f.errors) #獲取錯誤對象 return render(request, 'app1/index.html',{'cuow':f.errors}) # 打開頁面,將錯誤信息用字典方式傳到html頁面
3、在html頁面接收邏輯處理以字典形式傳過來的錯誤對象,分別獲取不同表單的錯誤信息
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/css/tou.css"> </head> <body> <form action="/bugarticles/" method="post"> <div> <input type="text" name="user"/> <span>{{ cuow.user.0 }}</span> <!-- 接收錯誤信息里的user的錯誤信息 --> </div> <div> <input type="text" name="pwd"/> <span>{{ cuow.pwd.0 }}</span> <!-- 接收錯誤信息里的pwd的錯誤信息 --> </div> <div> <input type="submit" value="提交"/> </div> </form> </body> </html>
利用表單類自動創建表單標簽
以上表單的<input>是我們自己手動寫的,還可以用表單類來自動創建表單標簽,好處是不用自己寫表單標簽,還有就是當用戶填寫的表單不合法提交時提示錯誤信息不清空表單
注意:表單類根據字段創建的表單標簽,當用戶輸入內容時,首先要經過瀏覽器默認行為的表單驗證,如果瀏覽器默認行為的表單驗證都沒有通過那么將無法提交
瀏覽器默認行為的表單驗證,通過了在進行我們定義的表單類驗證,驗證合法獲取用戶提交信息,不合法返回錯誤信息
利用表單類自動創建表單標簽
1、首先在get訪問頁面時,創建表單類不傳參數,然后把這個表單類傳到html頁面,在html頁面通過,表單類.字段名稱,來自動創建表單標簽
每一種表單字段類型,都有一個默認的表單標簽,這個標簽是可以更改的,所以表單類可以創建任何表單標簽
2、在post訪問時,再次創建表單類需要傳參,將post請求對象傳入表單類進行驗證表單,如果表單不合法,將錯誤信息對象傳到html顯示錯誤信息,將這次創建的表單類傳到html頁面替換get時創建的表單類
邏輯處理
from django.shortcuts import render from app1.models import * #導入數據庫操作模塊 from app1.biaodan import * #導入自定義表單驗證模塊 #邏輯處理模塊 def special(request): if request.method == 'GET': f = yhbd() #創建表單驗證類,不傳參 return render(request, 'app1/index.html',{'form':f}) # 打開頁面,並將表單驗證類傳到html生成表單標簽 if request.method == "POST": f = yhbd(request.POST) #創建驗證表單類,將用戶請求POST對象傳進表單驗證類進行驗證 if f.is_valid(): #判斷驗證如果通過 print(f.cleaned_data) #獲取到用戶提交信息,字典方式 else: #如果沒通過 # print(f.errors) #獲取錯誤對象 pass return render(request, 'app1/index.html',{'cuow':f.errors,'form':f}) # 打開頁面,將錯誤信息用字典方式傳到html頁面,並且將表單類傳到html頁面替換沒傳參的表單驗證類
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" type="text/css" href="/static/css/tou.css"> </head> <body> <form action="/bugarticles/" method="post"> <div> {{ form.user }} <!-- 接收get請求時創建的表單類,生成表單標簽 --> {% if cuow.user.0 %} <span class="cuow">{{ cuow.user.0 }}</span> <!-- 接收錯誤信息里的user的錯誤信息 --> {% endif %} </div> <div> {{ form.pwd }} <!-- 接收get請求時創建的表單類,生成表單標簽 --> {% if cuow.pwd.0 %} <span class="cuow">{{ cuow.pwd.0 }}</span> <!-- 接收錯誤信息里的pwd的錯誤信息 --> {% endif %} </div> <div> <input type="submit" value="提交"/> </div> </form> </body> </html>
常用的內置驗證字段
EmailField()驗證郵箱字段
CharField()驗證字符串字段
URLField()驗證url地址字段
IntegerField()驗證數字字段
GenericIPAddressField()驗證IP字段
注意:雖然有很多內置驗證字段,但是我們還是要根據我們自己的需求來驗證,所以
驗證字段的參數
required設置字段是否可以為空
True不可以為空
False可以為空
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField(required=True) #True不可以為空 pwd = forms.CharField()
max_length最大字符數
min_length最小字符數
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField(max_length=4,min_length=2) pwd = forms.CharField()
error_messages自定義錯誤提示信息
參數是一個字典{'驗證名稱':'錯誤提示'}
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) pwd = forms.CharField()
invalid設置郵箱格式錯誤提示信息
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) pwd = forms.EmailField( error_messages={ 'required': '郵箱不能為空', 'invalid':'郵箱格式不正確' } )
widget設置表單字段在html頁面的類型
使用方式:widget=forms.Textarea()
Textarea(): <textarea>標簽類型
TextInput():<input>標簽類型
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) pwd = forms.CharField( widget=forms.TextInput(), )
attrs給表單標簽設置屬性,可以給標簽元素設置class樣式,和input標簽的各種type屬性
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) pwd = forms.CharField( widget=forms.TextInput(attrs={'type':'password','class':'c1'}), )
Select生成表單,select標簽,下拉選項框
參數:
choices設置下拉數據,元組類型
attrs設置select標簽屬性
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) zhi = ( (0, '普通會員'), (1, '超級會員'), (2, '黃金會員'), (3, '白銀會員'), (4, 'vip會員') ) pwd = forms.CharField( widget=forms.widgets.Select(choices=zhi,attrs={'class':'c1'}) )
下拉框結合數據庫應用
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 from app1.models import * #導入數據庫操作 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) a = shengf.objects.all().values_list('id','shf') #獲取數據庫里shengf表里的id和shf字段的數據 pwd = forms.CharField( widget=forms.widgets.Select(choices=a,attrs={'class':'c1'}) #將數據庫的數據顯示到下拉框 )
下拉框結合數據庫應用,防止數據庫添加了數據,或者刪除了數據,頁面緩存了下拉框數據,無法事實數據同步
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 from app1.models import * #導入數據庫操作 class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) a = shengf.objects.all().values_list('id','shf') #獲取數據庫里shengf表里的id和shf字段的數據 pwd = forms.CharField( widget=forms.widgets.Select(choices=a,attrs={'class':'c1'}) #將數據庫的數據顯示到下拉框 ) #防止數據庫添加了數據,或者刪除了數據,頁面緩存了下拉框數據,無法事實數據同步 def __init__(self,*args, **kwargs): #創建類的__init__方法,每次創建類時都會執行 super(yhbd,self).__init__(*args, **kwargs) #獲取當前類的父類里的__init__方法執行 a = shengf.objects.all().values_list('id', 'shf') #重新獲取數據庫里shengf表里的id和shf字段的數據 self.fields['pwd'] = forms.CharField(widget=forms.widgets.Select(choices=a,attrs={'class':'c1'})) #更新一下表單pwd字段的數據
自定義驗證規則
validators設置自定義驗證規則,參數是一個列表,列表里是自定義驗證方法名稱
#!/usr/bin/env python # -*- coding:utf-8 -*- #表單驗證 from django import forms #導入Django的表單驗證模塊 from django.core.exceptions import ValidationError import re class yhbd(forms.Form): #自定義驗證表單類,繼承Django的表單驗證類 user = forms.CharField( required=True, max_length=4, min_length=2, error_messages={ 'required':'用戶名不能為空', 'max_length':'最大長度不得超過4個字符', 'min_length':'最小長度不得少於2個字符' } ) #自定義驗證規則 def shouji(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') #如果不匹配返回錯誤信息 pwd = forms.CharField( validators=[shouji, ], #設置自定義驗證規則 required=True, widget=forms.TextInput( attrs={ 'class': "cl", 'placeholder': u'手機號碼' } ), error_messages={ 'required':'手機不能為空', } )
其他
#!/usr/bin/env python # -*- coding:utf-8 -*- import re from django import forms from django.core.exceptions import ValidationError def mobile_validate(value): mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') if not mobile_re.match(value): raise ValidationError('手機號碼格式錯誤') class PublishForm(forms.Form): user_type_choice = ( (0, u'普通用戶'), (1, u'高級用戶'), ) user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, attrs={'class': "form-control"})) title = forms.CharField(max_length=20, min_length=5, error_messages={'required': u'標題不能為空', 'min_length': u'標題最少為5個字符', 'max_length': u'標題最多為20個字符'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'標題5-20個字符'})) memo = forms.CharField(required=False, max_length=256, widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3})) phone = forms.CharField(validators=[mobile_validate, ], error_messages={'required': u'手機不能為空'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'手機號碼'})) email = forms.EmailField(required=False, error_messages={'required': u'郵箱不能為空','invalid': u'郵箱格式錯誤'}, widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
注意:如果表單是通過Ajax提交的,頁面不刷新,那么html頁面將無法獲取到錯誤信息,那么我們只能將所有錯誤信息構造成字典,然后以json的方式返回給Ajax,添加到頁面
將models數據庫表類轉換成表單驗證類【必要使用】
這樣可以少寫表單驗證代碼,使用的是數據庫字段的驗證規則
models.py
from django.db import models # 導入models對象 class CourseOrg(models.Model): name = models.CharField(max_length=50, verbose_name='機構名稱') desc = models.TextField(verbose_name='機構描述') category = models.CharField(max_length=20, verbose_name='機構類別', default='pxjg', choices=(('pxjg', '培訓機構'), ('gx', '高校'), ('gr', '個人'))) click = models.IntegerField(default=0, verbose_name='點擊數') fav_nums = models.IntegerField(default=0, verbose_name='收藏數') image = models.ImageField(upload_to='org/%Y/%m', storage=ImageStorage(), verbose_name='封面圖', max_length=100) address = models.CharField(max_length=150, verbose_name='機構地址') city = models.ForeignKey(CityDict, verbose_name='外鍵城市表') add_time = models.DateTimeField(default=datetime.now, verbose_name='添加日期') class Meta: verbose_name = '課程機構表' verbose_name_plural = verbose_name def __str__(self): return self.name
forms.py
#!/usr/bin/env python # -*- coding:utf8 -*- from django import forms # 導入Django的表單驗證模塊 from app_organization.models import CourseOrg # 導入數據庫表類 class CourseOrgForm(forms.ModelForm): zdyi = forms.CharField() # 自定義表單驗證字段 class Meta: model = CourseOrg # 設置要將數據庫表類轉換成表單驗證類的名稱 fields = ['name','category','fav_nums'] # 要使用的字段