Form表單驗證本質:
- 就是一個類class MyForm(forms.Form) 繼承了forms.Form
form組件的主要功能如下:
- 生成頁面可用的HTML標簽
- 對用戶提交的數據進行校驗
- 保留上次輸入內容
使用form組件添加用戶信息的功能
# 自定義Form類
from django import forms class UserInfoForm(Form): # 表單的字段名字最好和model的字段名字一致,方便操作 username = forms.CharField( min_length=5, max_length=32, error_messages={ 'required':'不能為空', 'min_length':'最短5個字符', 'max_length':'最長32的字符' }, label="用戶名", )
pwd = forms.CharField( min_length=6, # Form表單默認生成<input type='text'/> 標簽 如果要修改可以使用widgets組件 或者 填寫 attr屬性 # widget=widgets.PasswordInput() widget=widgets.TextInput(attrs={'type': 'password'}) ) #------ 生成select標簽的兩種形式 ----- # 第一種后台接受到的數據是整數{'city_id': 1} city_id = forms.IntegerField( widget=widgets.Select( choices=[(1,'北京'),(2,'天津'),(3,'上海')], # 可以添加option標簽 接受列表格式的數據 每個元組對應value 和 text文本 attrs = {'id': '001', 'class':'cls-01','diy':'自定義'} # 可以設置屬性值 添加id class 名 自定義屬性 ) ) # 第二種接受的數據是字符串{'hobby': '1'} hobby = forms.ChoiceField( choices=((1, "籃球"), (2, "足球"), (3, "雙色球"),), label="愛好", initial=3, widget=forms.widgets.Select() )
# html代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶注冊</title> </head> <body> <h1>用戶信息注冊</h1> <form method="POST" action="/add_userinfo.html"> {% csrf_token %} <p> {{ userinfo_form.username }}{{ login_form.username.errors.0 }} </p> <p> {{ userinfo_form.pwd }}{{ userinfo_form.pwd.errors.0 }} </p> <p> {{ userinfo_form.city_id }}{{userinfo_form.city_id.errors.0 }} </p> <p> {{ userinfo_form.hobby }}{{ userinfo_form.hobby.errors.0 }} </p> <input type="submit" value="提交" /> </form> </body> </html>
# view.py
def userinfo(request): if request.method == 'GET': userinfo_form = UserInfoForm() return render(request, 'userinfo.html', {'userinfo_form': userinfo_form}) else: userinfo_form = UserInfoForm(request.POST) # 校驗數據的有效性 成功則向數據庫添加數據 if userinfo_form.is_valid(): models.UserInfo.objects.create(**userinfo_form.cleaned_data) return redirect('/userinfo.html') else: #失敗則將用戶提交的表單數據和表單html再次返回給用戶 return render(request, 'userinfo.html', {'userinfo_form': userinfo_form})
Form表單字段的參數:
# 參數分為2大類
# Field(
# 1. 數據校驗
# required=True, 不可以為空,默認可以不寫
# error_messages=None, 設置錯誤信息dict格式{'required':'不能為空','min_length':'長度最小是5'}
# validators=(), 自定義正則規則,傳入一個列表, 可以傳入多個規則 也可以傳入函數 def 函數名(value):pass
# 2. 自動生成html標(除了widget,其他不建議使用)
# widget=None, 自定義顯示在前端的表單控件
# initial 默認顯示的值
# label=None,
# help_text='',
# show_hidden_initial=False,
# localize=False,
# disabled=False,
# label_suffix=None
# )
Form表單的所有內置字段:
Field required=True 是否運行為空 widget=None, HTML插件 label=None, 用於生成label標簽或顯示內容 initial=None, 初始值 help_text=' ', 幫助信息(在標簽旁顯示) error_messages=None 錯誤信息{'required': '不能為空', 'invalid': '格式錯誤'} validators=[] 自定義驗證規則 localize=False, 是否支持本地化 disabled=False, 是否可以編輯 label_suffix=None Label內容后綴 CharField(Field) max_length=None 最大長度 min_length=None 最小長度 strip=True 是否移除用戶輸入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 總長度 decimal_places=None, 小數位長度 BaseTemporalField(Field) input_formats=None 時間格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 RegexField(CharField) regex, 自定制正則表達式 max_length=None, 最大長度 min_length=None, 最小長度 error_message=None, 忽略,錯誤信息使用 error_messages={'invalid': '...'} FileField(Field) allow_empty_file=False 是否允許空文件 ImageField(FileField) ... 注:需要PIL模塊,pip3 install Pillow 以上兩個字典使用時,需要注意兩點: - form表單中 enctype="multipart/form-data" - view函數中 obj = MyForm(request.POST, request.FILES) ChoiceField(Field) choices=(), 選項,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默認select插件 label=None, Label內容 initial=None, 初始值 help_text='', 幫助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查詢數據庫中的數據 empty_label="---------", # 默認空顯示內容 to_field_name=None, # HTML中value的值對應的字段 limit_choices_to=None # ModelForm中對queryset二次篩選 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 對選中的值進行一次轉換 empty_value= '' 空值的默認值 TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 對選中的每一個值進行一次轉換 empty_value= '' 空值的默認值 FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 path, 文件夾路徑 match=None, 正則匹配 recursive=False, 遞歸下面的文件夾 allow_files=True, 允許文件 allow_folders=False, 允許文件夾 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1時候,可解析為192.0.2.1, PS:protocol必須為both才能啟用 SlugField(CharField) 數字,字母,下划線,減號(連字符) UUIDField(CharField) uuid類型 Django Form內置字段
默認生成的html標簽樣式:
CharField --> input標簽 <input type="text" />
ChoiceFiled --> select標簽 <select></select>
如果需要修改標簽類型,需要使用widget參數
initial
設置初始值的兩種方式:
# 一、在Form表單字段中設置初始值 class UserInfoForm(Form): # 表單的字段名字最好和model的字段名字一致,方便操作 username = fields.CharField( min_length=5, max_length=32, initial='我是在html上首次顯示的初始值' # 設置初始值 ) ... # 二、實例化Form類時設置初始值 def test(request): userinfo_form = UserInfoForm(initial={'字段名1': '初始值1','字段名2': '初始值2'}) return render(request, 'userinfo.html', {'userinfo_form':userinfo_form})
自定義錯誤信息 error_messages
class UserInfoForm(Form): username = fields.CharField( min_length=5, max_length=32, error_messages={ 'required':'不能為空', 'min_length':'最短5個字符', 'max_length':'最長32的字符' } )
給Form指定字段的標簽添加屬性
city_id = fields.IntegerField( widget=widgets.Select( choices=[(1,'北京'),(2,'天津'),(3,'上海'),(4,"武漢")], # 可以添加option標簽 接受列表格式的數據 每個元組對應value 和 text文本 attrs = {'id': '001', 'class':'cls-01','diy':'自定義'} # 可以設置屬性值 添加id class 名 自定義屬性 ) )
使用內置字段 forms.RegexField 和參數 validators 自定義驗證規則
# forms.RegexField
phone = forms.RegexField(r'^1[35678]\d{9}$', max_length=11)
# validators
phone = forms.CharField( min_length=11, max_length=11, validators=[RegexValidator(r'^1[345678]\d{9}$', '手機號格式不正確'), RegexValidator(),...] # 可以傳入多個規則 )
# 還可以自定義校驗函數傳入 validators
# 自定義校驗函數 def phone_validate(value): # 拿用戶填寫的手機號去數據庫中校驗 is_exits = models.PhoneInfo.objects.filter(phone=value) if is_exits: # 如果手機號被注冊,不能再注冊 raise ValidationError("該手機號已經被注冊") else: return value phone = forms.CharField( max_length=11, validators=[RegexValidator(r'^1[345678]\d{9}$', '手機號格式不正確'), phone_validate] )