1. 程式人生 > >Django之Form組件(一)

Django之Form組件(一)

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 fields
4 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 SelectDateWidget
View 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組件(一)