在web端與後端交互時,咱們除了使用html原生的form標籤,還可使用django自帶的表單。html
Django 提供普遍的工具和庫來幫助你構建表單來接收網站訪問者的輸入,而後處理以及響應輸入。前端
在HTML中,表單的做用是收集標籤中的內容,<form>...</form>
中間能夠由訪問者添加相似於文本,選擇,或者一些控制模塊等等.而後這些內容將會被送到服務端web
某些表單的元素 —— 文本輸入和複選框 —— 很是簡單並且內建於HTML 自己。 其餘的複雜得多;彈出日期選擇器或容許您移動滑塊或操縱控件的界面一般將使用JavaScript和CSS以及HTML表單<input>
元素來實現這些效果。數據庫
與<input>
元素同樣,一個表單必須指定兩樣東西:django
Django 的登陸表單使用POST
方法,在這個方法中瀏覽器組合表單數據、對它們進行編碼以用於傳輸、將它們發送到服務器而後接收它的響應。後端
相反,GET
組合提交的數據爲一個字符串,而後使用它來生成一個URL。 這個URL 將包含數據發送的地址以及數據的鍵和值。瀏覽器
post和get用於不一樣的目的:安全
用於改變系統狀態的請求 —— 例如,給數據庫帶來變化的請求 —— 應該使用POST
。 GET
只應該用於不會影響系統狀態的請求。服務器
GET
還不適合密碼錶單,由於密碼將出如今URL 中,以及瀏覽器的歷史和服務器的日誌中,並且都是以普通的文本格式。 它還不適合數據量大的表單和二進制數據,例如一張圖片。 使用GET
請求做爲管理站點的表單具備安全隱患:攻擊者很容易模擬表單請求來取得系統的敏感數據。 POST
,若是與其它的保護措施結合將對訪問提供更多的控制,例如Django 的CSRF protection。app
另外一個方面,GET
適合網頁搜索這樣的表單,由於這種表示一個GET
請求的URL 能夠很容易地做爲書籤、分享和從新提交
在一個Web 應用中,"表單"可能指HTML <form>
、或者生成它的Django 的Form
、或者提交時發送的結構化數據、或者這些部分的總和。
django的FORM類
表單系統的核心部分是Django 的Form
類。 Django 的模型描述一個對象的邏輯結構、行爲以及展示給咱們的方式,與此相似,Form
類描述一個表單並決定它如何工做和展示。
就像模型類的屬性映射到數據庫的字段同樣,表單類的字段會映射到HTML 的<input>
表單的元素。 (ModelForm
經過一個Form
映射模型類的字段到HTML 表單的<input>
元素;Django 的Admin 站點就是基於這個)。
一個表單的字段自己就是類;他們管理表單數據,並在提交表單時執行驗證。 DateField
和FileField
處理的數據類型差異很大,必須完成不一樣的事情。
表單字段在瀏覽器中呈現給用戶的是一個HTML 的「widget」 —— 用戶界面的一個片斷。 每一個字段類型都有一個合適的默認Widget class,須要時能夠覆蓋。
構建表單
構建一個表單,獲取用戶的輸入信息便可!
正常使用html寫django提交表單以下:
<form action="/info/" method="post"> <label for="meg">請輸入信息</label> <input type="text" id="meg"><br> <input type="submit" value="提交"> {% csrf_token %} </form>
隨着業務邏輯的應用,咱們可能須要愈來愈多的input標籤,而且還須要對標籤輸入的內容作一些處理等等。所以爲了更方便的處理表單提交,django引入了FORM類。
一個簡單的表單應用以下:
由於比較簡單咱們把Form表單與視圖函數寫在了一個文件中(不推薦):
# *-* coding:utf-8 *-* from django.shortcuts import render # Create your views here. from django import forms class InfoForm(forms.Form): info = forms.CharField(label=u"用戶信息", max_length=100) #注意這裏的類屬性定義的info不能省略,否則不會再前端顯示 infoform = InfoForm() #實例化表單數據,而且把表單實例對象傳遞給html頁面 def info(request): return render(request, "info.html", {"infoform": infoform})
它定義一個Form
類,只帶有一個字段(info
)。 咱們已經對這個字段使用一我的性化的標籤,當渲染時它將出如今<label>
中(在這個例子中,即便咱們省略它,咱們指定的label
仍是會自動生成)。
字段容許的最大長度經過max_length
定義。 它完成兩件事情。 首先,它在HTML 的<input>
上放置一個maxlength="100"
(這樣瀏覽器將在第一時間阻止用戶輸入多於這個數目的字符)。 它還意味着當Django 收到瀏覽器發送過來的表單時,它將驗證數據的長度。
Form
的實例具備一個is_valid()
方法,它爲全部的字段運行驗證的程序。 當調用這個方法時,若是全部的字段都包含合法的數據,它將:
True
cleaned_data
屬性中。前端代碼以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/info/" method="post"> {{ infoform }} <input type="submit" value="提交"> {% csrf_token %} #這個是django爲了表單的安全驗證必須添加,若不想添加能夠如今中間件哪裏註釋掉對應的驗證。 </form> </body> </html>
展現效果以下:
格式須要本身寫!
上面咱們把表單的數據提交了,那麼在後臺改如何處理呢?咱們知道視圖層的做用就是做爲先後端交互的中間層,那麼表單提交的數據天然也是在視圖層處理了。
# *-* coding:utf-8 *-* from django.shortcuts import render, HttpResponse # Create your views here. from django import forms class InfoForm(forms.Form): info = forms.CharField(label=u"用戶信息 ", max_length=100) infoform = InfoForm() def info(request): if request.method == "GET": #如果GET訪問,則是直接訪問上面這個表單頁面 return render(request, "info.html", {"infoform": infoform}) elif request.method == "POST": #如果POST訪問,而後提取數據,處理數據 form = InfoForm(request.POST) #首先把request.POST對象做爲參數傳遞給InfoForm來實例化,經過表單的方式來處理數據 if form.is_valid(): #is_valid()方法上面提到過、 print "OK" print form.cleaned_data #打印出表單提交的數據,返回的是一個字典。 return HttpResponse("<h1>提交成功</h1>") else: return HttpResponse("error")
打印的結果是一個字典:
{'info': u'i have a dream'}
#這裏使用了cleaned_data方法,這個方法返回的是表單提交數據信息(咱們須要的數據),這裏僅僅有咱們須要的用戶輸入的信息。
#固然這裏的表單處理,依然可使用以前的request.POST方法來處理。
視圖的整個邏輯是這樣的:
若是訪問視圖的是一個GET 請求,它將建立一個空的表單實例並將它放置到要渲染的模板的上下文中。 這是咱們在第一次訪問該URL 時預期發生的狀況。 若是使用POST請求提交表單,該視圖將再次建立一個表單實例,並使用請求中的數據填充表單:形式 = NameForm(request.POST)這被稱爲「將數據綁定到表單」(如今是綁定的形式)。 咱們調用窗體的is_valid()方法;若是不是True,咱們返回到表單的模板。 這時表單再也不爲空(未綁定),因此HTML 表單將用以前提交的數據填充,而後能夠根據要求編輯並改正它。 若是True 爲is_valid(),咱們將可以在cleaned_data 屬性中找到全部合法的表單數據。 在發送HTTP 重定向給瀏覽器告訴它下一步的去向以前,咱們能夠用這個數據來更新數據庫或者作其它處理。
上面經過了一個簡單的實例說明了django表單的使用流程,django表單的用法仍是很強大的,下面會詳細說明其用法。
全部的表單類都做爲django.forms.Form
的子類建立,包括你在Django 管理站點中遇到的ModelForm。
綁定和未綁定數據的表單:
表單的is_bound
屬性將告訴你一個表單是否具備綁定的數據。
把上面視圖函數中的print 「OK」位置換成下面的:
print form.is_bound #表單已經綁定則返回True,不然返回False ##結果 {'info': u'i have a dream'} #這個爲print cleanted_data打印的結果 True
無論表單提交的是什麼數據,一旦經過調用is_valid()
成功驗證(is_valid()
返回True
),驗證後的表單數據將位於form.cleaned_data
字典中。 這些數據已經爲你轉換好爲Python 的類型。
上面的實例中,咱們infoform表單被渲染爲label標籤和input標籤,這兩個標籤須要放入form表單中才可使用。這是表單的默認渲染方式。
咱們還能夠有如下的渲染方式:
{{ form.as_table }} 以表格的形式將它們渲染在<tr> 標籤中 {{ form.as_p }} 將它們渲染在<p> 標籤中 {{ form.as_ul }} 將它們渲染在<li> 標籤中
#實例
<ul>
{{ infoform.as_ul }}
</ul>
分解form表單:
上面在前端上面引用時,咱們直接引用了{{ infoform }}的形式,可是這個變量包含了許多數據,有時候咱們爲了本身渲染每一個部分,須要單獨的提取某個部分,而後處理:
屬性 說明 {{ field.label }} 字段對應的label信息 {{ field.label_tag }} 自動生成字段的label標籤,注意與{{ field.label }}的區別,它包含表單的。 例如,默認的 是一個冒號: {{ field.id_for_label }} 自定義字段標籤的id {{ field.value }} 當前字段的值,好比一個Email字段的值someone@example.com {{ field.html_name }} 指定字段生成的input標籤中name屬性的值 {{ field.help_text }} 字段的幫助信息 {{ field.errors }} 包含錯誤信息的元素 {{ field.is_hidden }} 用於判斷當前字段是否爲隱藏的字段,若是是,返回True {{ field.field }} 返回字段的參數列表。例如{{ char_field.field.max_length }}label_suffixlabel_suffix
隱藏字段的處理
若是你正在手工佈局模板中的一個表單,而不是依賴Django 默認的表單佈局,你可能但願將<input type="hidden">
字段與非隱藏的字段區別對待。 例如,由於隱藏的字段不會顯示,在該字段旁邊放置錯誤信息可能讓你的用戶感到困惑 —— 因此這些字段的錯誤應該有區別地來處理。
Django 提供兩個表單方法,它們容許你獨立地在隱藏的和可見的字段上迭代:visible_fields()
和hidden_fields()
。
{# Include the hidden fields #} #註釋信息 {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {# Include the visible fields #} #註釋信息 {% for field in form.visible_fields %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }} {{ field }} </div> {% endfor %}
這個示例沒有處理隱藏字段中的任何錯誤信息。 一般,隱藏字段中的錯誤意味着表單被篡改,由於正常的表單填寫不會改變它們。 然而,你也能夠很容易地爲這些表單錯誤插入一些錯誤信息顯示出來。
若是你的網站在多個地方對錶單使用相同的渲染邏輯,你能夠保存表單的循環到一個單獨的模板中來減小重複,而後在其它模板中使用include
標籤來重用它:
# In your form template: {% include "form_snippet.html" %} # In form_snippet.html: {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }} {{ field }} </div> {% endfor %}
若是傳遞到模板上下文中的表單對象具備一個不一樣的名稱,你可使用include
標籤的with
參數來對它起個別名:
{% include "form_snippet.html" with form=comment_form %}
django表單的字段:https://yiyibooks.cn/xx/Django_1.11.6/ref/forms/fields.html