django中表單處理

在web端與後端交互時,咱們除了使用html原生的form標籤,還可使用django自帶的表單。html

Django 提供普遍的工具和庫來幫助你構建表單來接收網站訪問者的輸入,而後處理以及響應輸入。前端

HTML表單

在HTML中,表單的做用是收集標籤中的內容,<form>...</form> 中間能夠由訪問者添加相似於文本,選擇,或者一些控制模塊等等.而後這些內容將會被送到服務端web

某些表單的元素 —— 文本輸入和複選框 —— 很是簡單並且內建於HTML 自己。 其餘的複雜得多;彈出日期選擇器或容許您移動滑塊或操縱控件的界面一般將使用JavaScript和CSS以及HTML表單<input>元素來實現這些效果。數據庫

<input> 元素同樣,一個表單必須指定兩樣東西:django

  • 目的地:響應用戶輸入數據的URL
  • 方式:發送數據所使用的HTTP 方法

GET和POST方法

Django 的登陸表單使用POST 方法,在這個方法中瀏覽器組合表單數據、對它們進行編碼以用於傳輸、將它們發送到服務器而後接收它的響應。後端

相反,GET 組合提交的數據爲一個字符串,而後使用它來生成一個URL。 這個URL 將包含數據發送的地址以及數據的鍵和值。瀏覽器

post和get用於不一樣的目的:安全

用於改變系統狀態的請求 —— 例如,給數據庫帶來變化的請求 —— 應該使用POSTGET 只應該用於不會影響系統狀態的請求。服務器

GET 還不適合密碼錶單,由於密碼將出如今URL 中,以及瀏覽器的歷史和服務器的日誌中,並且都是以普通的文本格式。 它還不適合數據量大的表單和二進制數據,例如一張圖片。 使用GET 請求做爲管理站點的表單具備安全隱患:攻擊者很容易模擬表單請求來取得系統的敏感數據。 POST,若是與其它的保護措施結合將對訪問提供更多的控制,例如Django 的CSRF protectionapp

另外一個方面,GET 適合網頁搜索這樣的表單,由於這種表示一個GET 請求的URL 能夠很容易地做爲書籤、分享和從新提交

django中的表單

在一個Web 應用中,"表單"可能指HTML <form>、或者生成它的Django 的Form、或者提交時發送的結構化數據、或者這些部分的總和。

django的FORM類

表單系統的核心部分是Django 的Form 類。 Django 的模型描述一個對象的邏輯結構、行爲以及展示給咱們的方式,與此相似,Form 類描述一個表單並決定它如何工做和展示。

就像模型類的屬性映射到數據庫的字段同樣,表單類的字段會映射到HTML 的<input>表單的元素。 ModelForm 經過一個Form 映射模型類的字段到HTML 表單的<input> 元素;Django 的Admin 站點就是基於這個)。

一個表單的字段自己就是類;他們管理表單數據,並在提交表單時執行驗證。 DateFieldFileField 處理的數據類型差異很大,必須完成不一樣的事情。

表單字段在瀏覽器中呈現給用戶的是一個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類

全部的表單類都做爲django.forms.Form 的子類建立,包括你在Django 管理站點中遇到的ModelForm

綁定和未綁定數據的表單:

  • 不包含數據的表單稱爲未綁定表單。 當render給用戶時,它將爲空或包含默認的值。
  • 包含數據的表單稱爲綁定表單,所以能夠用來檢驗數據是否合法。 若是渲染一個不合法的綁定的表單,它將包含內聯的錯誤信息,告訴用戶如何糾正數據。

表單的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

相關文章
相關標籤/搜索