Django之Form組件(一)
阿新 • • 發佈:2019-03-03
fad fifo tar elm response cal prot limit bsp
Django之Form組件(一)
Django的Form主要具有一下幾大功能: 生成HTML標簽 驗證用戶數據(顯示錯誤信息) HTML Form提交保留上次提交數據 初始化頁面顯示內容
基本操作:字段驗證並顯示錯誤信息,渲染標簽(生成HTML標簽),保留上次提交數據
1 from django.shortcuts import render,HttpResponse,redirect 2 from django import forms #引入模塊 3 from django.forms import fields4 5 6 class FiForm(forms.Form): #必須繼承forms.Form
7 user=fields.CharField(max_length=12,min_length=6,required=True, 8 error_messages={ 9 ‘required‘: ‘用戶名不能為空‘, 10 ‘max_length‘: ‘用戶名最大12位‘, 11 ‘min_length‘:‘用戶名最少6位‘,12 }) 13 14 pwd=fields.CharField(min_length=12,required=True, 15 error_messages={ 16 ‘required‘: ‘密碼不能為空‘, 17 ‘min_length‘: ‘密碼最少12位‘, 18 19 }) 20 age=fields.IntegerField(required=True,21 error_messages={ 22 ‘required‘: ‘年齡不能為空‘, 23 }) 24 email=fields.EmailField(required=True, 25 error_messages={ 26 ‘required‘:‘郵箱格式不對‘ 27 }) 28 29 def login1(request): 30 31 if request.method ==‘GET‘: 32 obj=FiForm()#第一次生成FiForm對象,沒有傳參,生成HTML代碼 33 return render(request,"login1.html",{‘obj‘:obj}) 34 else: 35 u=request.POST.get(‘user‘) #不能為空,長度6-12 36 p=request.POST.get(‘passwd‘) #不能為空,長度12 37 e = request.POST.get(‘email‘)#不能為空,郵箱格式 38 a = request.POST.get(‘age‘)#不能為空,數字類型 39 print(u,p,e,a) 40 #檢查是否為空 41 #檢查格式 42 obj=FiForm(request.POST) #傳入數據進行字段驗證,form表單的name屬性值應該與forms組件的字段名稱一致,不一致的鍵值不會去做校驗。
43 #是否全部驗證成功,返回true或false 44 if obj.is_valid(): 45 經過驗證後得到的的數據 46 print(‘驗證成功‘,obj.cleaned_data) 47 else: 48 print(‘驗證失敗‘,obj.errors) # 字段不符合要求的對應的鍵作為鍵,錯誤信息作為值 <ul class="errorlist"><li>r_pwd<ul class="errorlist">... 49 return render(request,"login1.html",{‘obj‘:obj}) #傳入obj對象
分析:
(1)引入模塊
from django import forms from django.forms import fields
(2)生成驗證類
class FiForm(forms.Form): user=fields.CharField(max_length=12,min_length=6,required=True, error_messages={ ‘required‘: ‘用戶名不能為空‘, ‘max_length‘: ‘用戶名最大12位‘, ‘min_length‘:‘用戶名最少6位‘, }) pwd=fields.CharField(min_length=12,required=True, error_messages={ ‘required‘: ‘密碼不能為空‘, ‘min_length‘: ‘密碼最少12位‘, }) age=fields.IntegerField(required=True, error_messages={ ‘required‘: ‘年齡不能為空‘, }) email=fields.EmailField(required=True, error_messages={ ‘required‘:‘郵箱格式不對‘ })
(3)生成forms對象,需要註意的是給對象傳入字典就可以做一個個值的校驗:
例:form = UserForm({"name": "yuan", "email": "[email protected]", "xxx":"alex"}) obj=FiForm(request.POST) 註意:form表單的name屬性值應該與forms組件的字段名稱一致,不一致的鍵值不會去做校驗
(4)
form.is_valid() :做校驗返回布爾值的,所有都通過才返回True,否則返回False。與forms組件字段無關的鍵值不影響返回結果。
form.cleaned_data:字段值符合要求的放在cleaned_data中。字典數據類型。
form.errors:字段不符合要求的對應的鍵作為鍵,錯誤信息作為值。雖然返回結果比較復雜,但依然是字典數據類型,可以通過form.errors.get(“不符合的鍵”)來拿到鍵值,鍵值為列表數據類型。因此可以通過form.errors.get("不符合鍵")[0]拿到錯誤信息。
form.errors.get("pwd") #在後端取
{{ obj.errors.user.0 }} #在前端取,obj為傳過去的對象。
(5)去掉瀏覽器的驗證機制
如果你的表單包含URLField``EmailField 或其它整數字段類型,Django 將使用number、url和 email 這樣的HTML5 輸入類型。 默認情況下,瀏覽器可能會對這些字段進行它們自身的驗證,這些驗證可能比Django 的驗證更嚴格。 如果你想禁用這個行為,請設置form 標簽的novalidate屬性,
或者指定一個不同的字段,如TextInput
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="/login1/" method="POST"> 9 {% csrf_token %} 10 <!--<p>用戶名:<input type="text" name="user">{{ obj.errors.user.0 }}</p>--> 11 <!--<p>密碼:<input type="password" name="passwd">{{ obj.errors.pwd.0 }}</p>--> 12 <!--<p>郵箱:<input type="text" name="email">{{ obj.errors.email.0 }}</p>--> 13 <!--<p>年齡:<input type="text" name="age">{{ obj.errors.age.0 }}</p>--> 14 <p>用戶名:{{ obj.user }}{{ obj.errors.user.0 }}</p> 15 <p>密碼:{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p> 16 <p>郵箱:{{ obj.email }}{{ obj.errors.email.0 }}</p> 17 <p>年齡:{{ obj.age }}{{ obj.errors.age.0 }}</p> 18 <p><input type="submit" value="提交"></p> 19 20 </form> 21 22 </body> 23 </html>
渲染
第一種渲染方式
form = UserForm()
註意:任何一個Field都有兩個功能:驗證和插件。
from django import forms # 引入forms組件 class UserForm(forms.Form): # 必須繼承forms.Form # forms.CharField和forms.EmailField會渲染為input標簽 name = forms.CharField(min_length=4) # 默認label是字段名 pwd = forms.CharField(min_length=4, label="密碼") # 如果需要中文label可以手動設置 r_pwd = forms.CharField(min_length=4, label="確認密碼") email = forms.EmailField(label="郵箱") tel = forms.CharField(label="手機") def reg(request): form = UserForm() return render(request, "reg.html", locals())
<h3>form組件渲染方式1</h3> <form action="" method="post"> {% csrf_token %} <p>{{ form.name.label }} {{ form.name }} </p> <p>{{ form.pwd.label }} {{ form.pwd }} </p> <p>{{ form.r_pwd.label }} {{ form.r_pwd }} </p> <p>{{ form.email.label }} {{ form.email }} </p> <p>{{ form.tel.label }} {{ form.tel }} </p> <input type="submit"> </form>
第二種渲染方式
調用form對象的組件,即完成渲染。缺點是結構固定
{{ form.as_table }} 以表格的形式將它們渲染在<tr> 標簽中 {{ form.as_p }} 將它們渲染在<p> 標簽中 {{ form.as_ul }} 將它們渲染在<li> 標簽中
<hr> <h3>form組件渲染方式2</h3> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} </form>
初始化數據
在Web應用程序中開發編寫功能時,時常用到獲取數據庫中的數據並將值初始化在HTML中的標簽上。
if request.method ==‘GET‘: values = { ‘username‘: ‘root‘, ‘pwd‘: ‘123123‘, ‘email‘: ‘[email protected]‘, ‘age‘:12, } obj=FiForm(initial=values)
Form組件歸類
全部字段
1 每一個Field都有一個正則表達式和默認插件 2 3 4 5 6 7 8 創建Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML; 9 10 Field 11 required=True, 是否允許為空 12 widget=None, HTML插件 13 label=None, 用於生成Label標簽或顯示內容 14 initial=None, 初始值 15 help_text=‘‘, 幫助信息(在標簽旁邊顯示) 16 error_messages=None, 錯誤信息 {‘required‘: ‘不能為空‘, ‘invalid‘: ‘格式錯誤‘} 17 show_hidden_initial=False, 是否在當前插件後面再加一個隱藏的且具有默認值的插件(可用於檢驗兩次輸入是否一直) 18 validators=[], 自定義驗證規則 19 localize=False, 是否支持本地化 20 disabled=False, 是否可以編輯 21 label_suffix=None Label內容後綴 22 23 24 CharField(Field) 25 max_length=None, 最大長度 26 min_length=None, 最小長度 27 strip=True 是否移除用戶輸入空白 28 29 IntegerField(Field) 30 max_value=None, 最大值 31 min_value=None, 最小值 32 33 FloatField(IntegerField) 34 ... 35 36 DecimalField(IntegerField) 37 max_value=None, 最大值 38 min_value=None, 最小值 39 max_digits=None, 總長度 40 decimal_places=None, 小數位長度 41 42 BaseTemporalField(Field) 43 input_formats=None 時間格式化 44 45 DateField(BaseTemporalField) 格式:2015-09-01 46 TimeField(BaseTemporalField) 格式:11:12 47 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 48 49 DurationField(Field) 時間間隔:%d %H:%M:%S.%f 50 ... 51 52 RegexField(CharField) 53 regex, 自定制正則表達式 54 max_length=None, 最大長度 55 min_length=None, 最小長度 56 error_message=None, 忽略,錯誤信息使用 error_messages={‘invalid‘: ‘...‘} 57 58 EmailField(CharField) 59 ... 60 61 FileField(Field) 62 allow_empty_file=False 是否允許空文件 63 64 ImageField(FileField) 65 ... 66 註:需要PIL模塊,pip3 install Pillow 67 以上兩個字典使用時,需要註意兩點: 68 - form表單中 enctype="multipart/form-data" 69 - view函數中 obj = MyForm(request.POST, request.FILES) 70 71 URLField(Field) 72 ... 73 74 75 BooleanField(Field) 76 ... 77 78 NullBooleanField(BooleanField) 79 ... 80 81 ChoiceField(Field) 82 ... 83 choices=(), 選項,如:choices = ((0,‘上海‘),(1,‘北京‘),) 84 required=True, 是否必填 85 widget=None, 插件,默認select插件 86 label=None, Label內容 87 initial=None, 初始值 88 help_text=‘‘, 幫助提示 89 90 91 ModelChoiceField(ChoiceField) 92 ... django.forms.models.ModelChoiceField 93 queryset, # 查詢數據庫中的數據 94 empty_label="---------", # 默認空顯示內容 95 to_field_name=None, # HTML中value的值對應的字段 96 limit_choices_to=None # ModelForm中對queryset二次篩選 97 98 ModelMultipleChoiceField(ModelChoiceField) 99 ... django.forms.models.ModelMultipleChoiceField 100 101 102 103 TypedChoiceField(ChoiceField) 104 coerce = lambda val: val 對選中的值進行一次轉換 105 empty_value= ‘‘ 空值的默認值 106 107 MultipleChoiceField(ChoiceField) 108 ... 109 110 TypedMultipleChoiceField(MultipleChoiceField) 111 coerce = lambda val: val 對選中的每一個值進行一次轉換 112 empty_value= ‘‘ 空值的默認值 113 114 ComboField(Field) 115 fields=() 使用多個驗證,如下:即驗證最大長度20,又驗證郵箱格式 116 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) 117 118 MultiValueField(Field) 119 PS: 抽象類,子類中可以實現聚合多個字典去匹配一個值,要配合MultiWidget使用 120 121 SplitDateTimeField(MultiValueField) 122 input_date_formats=None, 格式列表:[‘%Y--%m--%d‘, ‘%m%d/%Y‘, ‘%m/%d/%y‘] 123 input_time_formats=None 格式列表:[‘%H:%M:%S‘, ‘%H:%M:%S.%f‘, ‘%H:%M‘] 124 125 FilePathField(ChoiceField) 文件選項,目錄下文件顯示在頁面中 126 path, 文件夾路徑 127 match=None, 正則匹配 128 recursive=False, 遞歸下面的文件夾 129 allow_files=True, 允許文件 130 allow_folders=False, 允許文件夾 131 required=True, 132 widget=None, 133 label=None, 134 initial=None, 135 help_text=‘‘ 136 137 GenericIPAddressField 138 protocol=‘both‘, both,ipv4,ipv6支持的IP格式 139 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1時候,可解析為192.0.2.1, PS:protocol必須為both才能啟用 140 141 SlugField(CharField) 數字,字母,下劃線,減號(連字符) 142 ... 143 144 UUIDField(CharField) uuid類型 145 ...View Code
補充:UUID
>>> import uuid # make a UUID based on the host ID and current time >>> uuid.uuid1() # doctest: +SKIP UUID(‘a8098c1a-f86e-11da-bd1a-00112444be1e‘) # make a UUID using an MD5 hash of a namespace UUID and a name >>> uuid.uuid3(uuid.NAMESPACE_DNS, ‘python.org‘) UUID(‘6fa459ea-ee8a-3ca4-894e-db77e160355e‘) # make a random UUID >>> uuid.uuid4() # doctest: +SKIP UUID(‘16fd2706-8baf-433b-82eb-8c7fada847da‘) # make a UUID using a SHA-1 hash of a namespace UUID and a name >>> uuid.uuid5(uuid.NAMESPACE_DNS, ‘python.org‘) UUID(‘886313e1-3b8a-5372-9b90-0c9aee199e5d‘) # make a UUID from a string of hex digits (braces and hyphens ignored) >>> x = uuid.UUID(‘{00010203-0405-0607-0809-0a0b0c0d0e0f}‘) # convert a UUID to a string of hex digits in standard form >>> str(x) ‘00010203-0405-0607-0809-0a0b0c0d0e0f‘ # get the raw 16 bytes of the UUID >>> x.bytes b‘\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f‘ # make a UUID from a 16-byte string >>> uuid.UUID(bytes=x.bytes) UUID(‘00010203-0405-0607-0809-0a0b0c0d0e0f‘)View Code
全部插件
1 TextInput(Input) 2 NumberInput(TextInput) 3 EmailInput(TextInput) 4 URLInput(TextInput) 5 PasswordInput(TextInput) 6 HiddenInput(TextInput) 7 Textarea(Widget) 8 DateInput(DateTimeBaseInput) 9 DateTimeInput(DateTimeBaseInput) 10 TimeInput(DateTimeBaseInput) 11 CheckboxInput 12 Select 13 NullBooleanSelect 14 SelectMultiple 15 RadioSelect 16 CheckboxSelectMultiple 17 FileInput 18 ClearableFileInput 19 MultipleHiddenInput 20 SplitDateTimeWidget 21 SplitHiddenDateTimeWidget 22 SelectDateWidgetView Code
常用選擇插件
1 # 單radio,值為字符串 2 # user = fields.CharField( 3 # initial=2, 4 # widget=widgets.RadioSelect(choices=((1,‘上海‘),(2,‘北京‘),)) 5 # ) 6 7 # 單radio,值為字符串 8 # user = fields.ChoiceField( 9 # choices=((1, ‘上海‘), (2, ‘北京‘),), 10 # initial=2, 11 # widget=widgets.RadioSelect 12 # ) 13 14 # 單select,值為字符串 15 # user = fields.CharField( 16 # initial=2, 17 # widget=widgets.Select(choices=((1,‘上海‘),(2,‘北京‘),)) 18 # ) 19 20 # 單select,值為字符串 21 # user = fields.ChoiceField( 22 # choices=((1, ‘上海‘), (2, ‘北京‘),), 23 # initial=2, 24 # widget=widgets.Select 25 # ) 26 27 # 多選select,值為列表 28 # user = fields.MultipleChoiceField( 29 # choices=((1,‘上海‘),(2,‘北京‘),), 30 # initial=[1,], 31 # widget=widgets.SelectMultiple 32 # ) 33 34 35 # 單checkbox 36 # user = fields.CharField( 37 # widget=widgets.CheckboxInput() 38 # ) 39 40 41 # 多選checkbox,值為列表 42 # user = fields.MultipleChoiceField( 43 # initial=[2, ], 44 # choices=((1, ‘上海‘), (2, ‘北京‘),), 45 # widget=widgets.CheckboxSelectMultiple 46 # )View Code
Django之Form組件(一)