鍍金池/ 教程/ Python/ 使用表單
點擊劫持保護(hù)
安全問題歸檔
Model 類參考
將遺留數(shù)據(jù)庫整合到Django
關(guān)聯(lián)對象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁
使用Django輸出CSV
加密簽名
文件儲存API
安全
Django中的測試
國際化和本地化
為Django編寫首個補丁
條件表達(dá)式
日志
模型元選項
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫訪問優(yōu)化
錯誤報告
基于類的內(nèi)建通用視圖
編寫自定義存儲系統(tǒng)
編寫你的第一個 Django 程序 第3部分
編寫數(shù)據(jù)庫遷移
使用表單
編寫你的第一個 Django 程序 第2部分
編寫你的第一個 Django 程序 第1部分
如何使用會話
系統(tǒng)檢查框架
新手入門
信號
編寫視圖
如何使用WSGI 部署
編寫你的第一個Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實例參考
視圖層
Django中的密碼管理
高級教程:如何編寫可重用的應(yīng)用
國際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過程
編寫你的第一個Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫
編寫你的第一個 Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗證器
使用Django輸出PDF
File對象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

使用表單

關(guān)于這頁文檔

這頁文檔簡單介紹Web 表單的基本概念和它們在Django 中是如何處理的。關(guān)于表單API 某方面的細(xì)節(jié),請參見表單 API、表單的字段和表單和字段的檢驗。

除非你計劃構(gòu)建的網(wǎng)站和應(yīng)用只是發(fā)布內(nèi)容而不接受訪問者的輸入,否則你將需要理解并使用表單。

Django 提供廣泛的工具和庫來幫助你構(gòu)建表單來接收網(wǎng)站訪問者的輸入,然后處理以及響應(yīng)輸入。

HTML 表單

在HTML中,表單是位于<form>...</form> 之間的元素的集合,它們允許訪問者輸入文本、選擇選項、操作對象和控制等等,然后將信息發(fā)送回服務(wù)器。

某些表單的元素 —— 文本輸入和復(fù)選框 —— 非常簡單而且內(nèi)建于HTML 本身。其它的表單會復(fù)雜些;例如彈出一個日期選擇對話框的界面、允許你移動滾動條的界面、使用JavaScript 和CSS 以及HTML 表單<input> 元素來實現(xiàn)操作控制的界面。

<input> 元素一樣,一個表單必須指定兩樣?xùn)|西:

  • where:響應(yīng)用戶輸入的URL
  • how:HTTP 方法

例如,Django Admin 站點的登錄表單包含幾個<input> 元素:type="text" 用于用戶名,type="password" 用于密碼,type="submit" 用于“Log in" 按鈕。它還包含一些用戶看不到的隱藏的文本字段,Django 使用它們來決定下一步的行為。

它還告訴瀏覽器表單數(shù)據(jù)應(yīng)該發(fā)往<form>action 屬性指定的URL —— /admin/,而且應(yīng)該使用method 屬性指定的HTTP 方法 —— post。

當(dāng)觸發(fā)<input type="submit" value="Log in"> 元素時,數(shù)據(jù)將發(fā)送給/admin/

GET 和 POST

處理表單時候只會用到GETPOST 方法。

Django 的登錄表單使用POST 方法,在這個方法中瀏覽器組合表單數(shù)據(jù)、對它們進(jìn)行編碼以用于傳輸、將它們發(fā)送到服務(wù)器然后接收它的響應(yīng)。

相反,GET 組合提交的數(shù)據(jù)為一個字符串,然后使用它來生成一個URL。這個URL 將包含數(shù)據(jù)發(fā)送的地址以及數(shù)據(jù)的鍵和值。如果你在Django 文檔中做一次搜索,你會立即看到這點,此時將生成一個https://docs.djangoproject.com/search/?q=forms&release=1 形式的URL。

GETPOST 用于不同的目的。

用于改變系統(tǒng)狀態(tài)的請求 —— 例如,給數(shù)據(jù)庫帶來變化的請求 —— 應(yīng)該使用POST。GET 只應(yīng)該用于不會影響系統(tǒng)狀態(tài)的請求。

GET 還不適合密碼表單,因為密碼將出現(xiàn)在URL 中,以及瀏覽器的歷史和服務(wù)器的日志中,而且都是以普通的文本格式。它還不適合數(shù)據(jù)量大的表單和二進(jìn)制數(shù)據(jù),例如一張圖片。使用GET 請求作為管理站點的表單具有安全隱患:攻擊者很容易模擬表單請求來取得系統(tǒng)的敏感數(shù)據(jù)。POST,如果與其它的保護(hù)措施結(jié)合將對訪問提供更多的控制,例如Django 的CSRF 保護(hù)。

另一個方面,GET 適合網(wǎng)頁搜索這樣的表單,因為這種表示一個GET 請求的URL 可以很容易地作為書簽、分享和重新提交。

Django 在表單中的角色

處理表單是一件很復(fù)雜的事情??紤]一下Django 的Admin 站點,不同類型的大量數(shù)據(jù)項需要在一個表單中準(zhǔn)備好、渲染成HTML、使用一個方便的界面編輯、返回給服務(wù)器、驗證并清除,然后保存或者向后繼續(xù)處理。

Django 的表單功能可以簡化并自動化大部分這些工作,而且還可以比大部分程序員自己所編寫的代碼更安全。

Django 會處理表單工作中的三個顯著不同的部分:

  • 準(zhǔn)備并重新構(gòu)造數(shù)據(jù)
  • 為數(shù)據(jù)創(chuàng)建HTML 表單
  • 接收并處理客戶端提交的表單和數(shù)據(jù)

可以手工編寫代碼來實現(xiàn),但是Django 可以幫你完成所有這些工作。

Django 中的表單

我們已經(jīng)簡短講述HTML 表單,但是HTML的<form> 只是其機制的一部分。

在一個Web 應(yīng)用中,‘表單’可能指HTML <form>、或者生成它的Django 的Form、或者提交時發(fā)送的結(jié)構(gòu)化數(shù)據(jù)、或者這些部分的總和。

Django 的Form 類

表單系統(tǒng)的核心部分是Django 的Form 類。Django 的模型描述一個對象的邏輯結(jié)構(gòu)、行為以及展現(xiàn)給我們的方式,與此類似,Form 類描述一個表單并決定它如何工作和展現(xiàn)。

模型類的字典映射到數(shù)據(jù)庫的字典,與此類似,表單類的字段映射到HTML 的表單<input> 元素。(ModelForm通過一個Form 映射模型類的字段到HTML 表單的<input>元素;Django 的Admin 站點就是基于這個)。

表單的字段本身也是類;它們管理表單的數(shù)據(jù)并在表單提交時進(jìn)行驗證。DateFieldFileField處理的數(shù)據(jù)類型差別很大,必須完成不同的事情。

表單字段在瀏覽器中呈現(xiàn)給用戶的是一個HTML 的“widget” —— 用戶界面的一個片段。每個字段類型都有一個合適的默認(rèn)Widget 類,需要時可以覆蓋。

實例化、處理和渲染表單

在Django 中渲染一個對象時,我們通常:

  1. 在視圖中獲得它(例如,從數(shù)據(jù)庫中獲?。?/li>
  2. 將它傳遞給模板上下文
  3. 使用模板變量將它擴展為HTML 標(biāo)記

在模板中渲染表單和渲染其它類型的對象幾乎一樣,除了幾個關(guān)鍵的差別。

在模型實例不包含數(shù)據(jù)的情況下,在模板中對它做處理很少有什么用處。但是渲染一個未填充的表單卻非常有意義 —— 我們希望用戶去填充它。

所以當(dāng)我們在視圖中處理模型實例時,我們一般從數(shù)據(jù)庫中獲取它。當(dāng)我們處理表單時,我們一般在視圖中實例化它。

當(dāng)我們實例化表單時,我們可以選擇讓它為空還是預(yù)先填充它,例如使用:

  • 來自一個保存后的模型實例的數(shù)據(jù)(例如用于編輯的管理表單)
  • 我們從其它地方獲得的數(shù)據(jù)
  • 從前面一個HTML 表單提交過來的數(shù)據(jù)

最后一種情況最令人關(guān)注,因為它使得用戶可以不只是閱讀一個網(wǎng)站,而且可以給網(wǎng)站返回信息。

構(gòu)建一個表單

需要完成的工作

假設(shè)你想在你的網(wǎng)站上創(chuàng)建一個簡單的表單,以獲得用戶的名字。你需要類似這樣的模板:

<form action="/your-name/" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

這告訴瀏覽器發(fā)送表單的數(shù)據(jù)到URL /your-name/,并使用POST 方法。它將顯示一個標(biāo)簽為"Your name:"的文本字段,和一個"OK"按鈕。如果模板上下文包含一個current_name 變量,它將用于預(yù)填充your_name 字段。

你將需要一個視圖來渲染這個包含HTML 表單的模板,并提供合適的current_name 字段。

當(dāng)表單提交時,發(fā)往服務(wù)器的POST 請求將包含表單數(shù)據(jù)。

現(xiàn)在你還需要一個對應(yīng)/your-name/ URL 的視圖,它在請求中找到正確的鍵/值對,然后處理它們。

這是一個非常簡單的表單。實際應(yīng)用中,一個表單可能包含幾十上百個字段,其中大部分需要預(yù)填充,而且我們預(yù)料到用戶將來回編輯-提交幾次才能完成操作。

我們可能需要在表單提交之前,在瀏覽器端作一些驗證。我們可能想使用非常復(fù)雜的字段,以允許用戶做類似從日歷中挑選日期這樣的事情,等等。

這個時候,讓Django 來為我們完成大部分工作是很容易的。

在Django 中構(gòu)建一個表單

Form 類

我們已經(jīng)計劃好了我們的 HTML 表單應(yīng)該呈現(xiàn)的樣子。在Django 中,我們的起始點是這里:

#forms.py

from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name', max_length=100)

它定義一個Form 類,只帶有一個字段(your_name)。我們已經(jīng)對這個字段使用一個友好的標(biāo)簽,當(dāng)渲染時它將出現(xiàn)在<label> 中(在這個例子中,即使我們省略它,我們指定的label還是會自動生成)。

字段允許的最大長度通過max_length 定義。它完成兩件事情。首先,它在HTML 的<input> 上放置一個maxlength="100" (這樣瀏覽器將在第一時間阻止用戶輸入多于這個數(shù)目的字符)。它還意味著當(dāng)Django 收到瀏覽器發(fā)送過來的表單時,它將驗證數(shù)據(jù)的長度。

Form 的實例具有一個is_valid() 方法,它為所有的字段運行驗證的程序。當(dāng)調(diào)用這個方法時,如果所有的字段都包含合法的數(shù)據(jù),它將:

  • 返回True
  • 將表單的數(shù)據(jù)放到cleaned_data屬性中。

完整的表單,第一次渲染時,看上去將像:

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">

注意它不包含 <form> 標(biāo)簽和提交按鈕。我們必須自己在模板中提供它們。

視圖

發(fā)送給Django 網(wǎng)站的表單數(shù)據(jù)通過一個視圖處理,一般和發(fā)布這個表單的是同一個視圖。這允許我們重用一些相同的邏輯。

當(dāng)處理表單時,我們需要在視圖中實例化它:

#views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect

from .forms import NameForm

def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'name.html', {'form': form})

如果訪問視圖的是一個GET 請求,它將創(chuàng)建一個空的表單實例并將它放置到要渲染的模板的上下文中。這是我們在第一個訪問該URL 時預(yù)期發(fā)生的情況。

如果表單的提交使用POST 請求,那么視圖將再次創(chuàng)建一個表單實例并使用請求中的數(shù)據(jù)填充它:form = NameForm(request.POST)。這叫做”綁定數(shù)據(jù)至表單“(它現(xiàn)在是一個綁定的表單)。

我們調(diào)用表單的is_valid()方法;如果它不為True,我們將帶著這個表單返回到模板。這時表單不再為空(未綁定),所以HTML 表單將用之前提交的數(shù)據(jù)填充,然后可以根據(jù)要求編輯并改正它。

如果is_valid()True,我們將能夠在cleaned_data 屬性中找到所有合法的表單數(shù)據(jù)。在發(fā)送HTTP 重定向給瀏覽器告訴它下一步的去向之前,我們可以用這個數(shù)據(jù)來更新數(shù)據(jù)庫或者做其它處理。

模板

我們不需要在name.html 模板中做很多工作。最簡單的例子是:

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

根據(jù){{ form }},所有的表單字段和它們的屬性將通過Django 的模板語言拆分成HTML 標(biāo)記 。

表單和跨站請求偽造的防護(hù)

Django 原生支持一個簡單易用的跨站請求偽造的防護(hù)。當(dāng)提交一個啟用CSRF 防護(hù)的POST 表單時,你必須使用上面例子中的csrf_token 模板標(biāo)簽。然而,因為CSRF 防護(hù)在模板中不是與表單直接捆綁在一起的,這個標(biāo)簽在這篇文檔的以下示例中將省略。

HTML5 輸入類型和瀏覽器驗證

如果你的表單包含URLFieldEmailField 和其它整數(shù)字段類似,Django 將使用urlemailnumber 這樣的HTML5 輸入類型。默認(rèn)情況下,瀏覽器可能會對這些字段進(jìn)行它們自身的驗證,這些驗證可能比Django 的驗證更嚴(yán)格。如果你想禁用這個行為,請設(shè)置form 標(biāo)簽的novalidate 屬性,或者指定一個不同的字段,如TextInput

現(xiàn)在我們有了一個可以工作的網(wǎng)頁表單,它通過Django Form 描述、通過視圖處理并渲染成一個HTML <form>。

這是你入門所需要知道的所有內(nèi)容,但是表單框架為了提供了更多的內(nèi)容。一旦你理解了上面描述的基本處理過程,你應(yīng)該可以理解表單系統(tǒng)的其它功能并準(zhǔn)備好學(xué)習(xí)更多的底層機制。

Django Form 類詳解

所有的表單類都作為django.forms.Form 的子類創(chuàng)建,包括你在Django 管理站點中遇到的ModelForm。

模型和表單

實際上,如果你的表單打算直接用來添加和編輯Django 的模型,ModelForm 可以節(jié)省你的許多時間、精力和代碼,因為它將根據(jù)Model 類構(gòu)建一個表單以及適當(dāng)?shù)淖侄魏蛯傩浴?/p>

綁定的和未綁定的表單實例

綁定的和未綁定的表單 之間的區(qū)別非常重要:

  • 未綁定的表單沒有關(guān)聯(lián)的數(shù)據(jù)。當(dāng)渲染給用戶時,它將為空或包含默認(rèn)的值。
  • 綁定的表單具有提交的數(shù)據(jù),因此可以用來檢驗數(shù)據(jù)是否合法。如果渲染一個不合法的綁定的表單,它將包含內(nèi)聯(lián)的錯誤信息,告訴用戶如何糾正數(shù)據(jù)。

表單的is_bound 屬性將告訴你一個表單是否具有綁定的數(shù)據(jù)。

字段詳解

考慮一個比上面的迷你示例更有用的一個表單,我們可以用它來在一個個人網(wǎng)站上實現(xiàn)“聯(lián)系我”功能:

#forms.py

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

我們前面的表單只使用一個字段your_name,它是一個CharField。在這個例子中,我們的表單具有四個字段:subject、message、sendercc_myself。共用到三種字段類型:CharField、EmailFieldBooleanField;完整的字段類型列表可以在表單字段中找到。

Widgets

每個表單字段都有一個對應(yīng)的Widget 類,它對應(yīng)一個HTML 表單Widget,例如<input type="text">。

在大部分情況下,字段都具有一個合理的默認(rèn)Widget。例如,默認(rèn)情況下,CharField 具有一個TextInput Widget,它在HTML 中生成一個<input type="text">。如果你需要<textarea>,在定義表單字段時你應(yīng)該指定一個合適的Widget,例如我們定義的message 字段。

字段的數(shù)據(jù)

不管表單提交的是什么數(shù)據(jù),一旦通過調(diào)用is_valid() 成功驗證(is_valid() 返回True),驗證后的表單數(shù)據(jù)將位于form.cleaned_data 字典中。這些數(shù)據(jù)已經(jīng)為你轉(zhuǎn)換好為Python 的類型。

此時,你依然可以從request.POST 中直接訪問到未驗證的數(shù)據(jù),但是訪問驗證后的數(shù)據(jù)更好一些。

在上面的聯(lián)系表單示例中,cc_myself 將是一個布爾值。類似地,IntegerFieldFloatField 字段分別將值轉(zhuǎn)換為Python 的intfloat。

下面是在視圖中如何處理表單數(shù)據(jù):

#views.py

from django.core.mail import send_mail

if form.is_valid():
    subject = form.cleaned_data['subject']
    message = form.cleaned_data['message']
    sender = form.cleaned_data['sender']
    cc_myself = form.cleaned_data['cc_myself']

    recipients = ['info@example.com']
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect('/thanks/')

提示

關(guān)于Django 中如何發(fā)送郵件的更多信息,請參見發(fā)送郵件。

有些字段類型需要一些額外的處理。例如,使用表單上傳的文件需要不同地處理(它們可以從request.FILES 獲取,而不是request.POST)。如何使用表單處理文件上傳的更多細(xì)節(jié),請參見綁定上傳的文件到一個表單。

使用表單模板

你需要做的就是將表單實例放進(jìn)模板的上下文。如果你的表單在Context 中叫做form,那么{{ form }}將正確地渲染它的<label><input>元素。

表單渲染的選項

表單模板的額外標(biāo)簽

不要忘記,表單的輸出不 包含<form>標(biāo)簽,和表單的submit 按鈕。你必須自己提供它們。

對于<label>/<input> 對,還有幾個輸出選項:

  • {{ form.as_table }} 以表格的形式將它們渲染在<tr> 標(biāo)簽中
  • {{ form.as_p }} 將它們渲染在<p> 標(biāo)簽中
  • {{ form.as_ul }} 將它們渲染在<li> 標(biāo)簽中

注意,你必須自己提供<table><ul> 元素。

下面是我們的ContactForm 實例的輸出{{ form.as_p }}

<p><label for="id_subject">Subject:</label>
    <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
<p><label for="id_message">Message:</label>
    <input type="text" name="message" id="id_message" /></p>
<p><label for="id_sender">Sender:</label>
    <input type="email" name="sender" id="id_sender" /></p>
<p><label for="id_cc_myself">Cc myself:</label>
    <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>

注意,每個表單字段具有一個ID屬性并設(shè)置為id_<field-name>,它被一起的label 標(biāo)簽引用。它對于確保屏幕閱讀軟件這類的輔助計算非常重要。你還可以自定義label 和 id 生成的方式。

更多信息參見 輸出表單為HTML。

手工渲染字段

我們沒有必要非要讓Django 來分拆表單的字段;如果我們喜歡,我們可以手工來做(例如,這樣允許重新對字段排序)。每個字段都是表單的一個屬性,可以使用{{ form.name_of_field }} 訪問,并將在Django 模板中正確地渲染。例如:

{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
    {{ form.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</div>

完整的<label> 元素還可以使用label_tag() 生成。例如:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
</div>

渲染表單的錯誤信息

當(dāng)然,這個便利性的代價是更多的工作。直到現(xiàn)在,我們沒有擔(dān)心如何展示錯誤信息,因為Django 已經(jīng)幫我們處理好。在下面的例子中,我們將自己處理每個字段的錯誤和表單整體的各種錯誤。注意,表單和模板頂部的{{ form.non_field_errors }} 查找每個字段的錯誤。

使用{{ form.name_of_field.errors }} 顯示表單錯誤的一個清單,并渲染成一個ul??瓷先タ赡芟瘢?/p>

<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

這個ul 有一個errorlist CSS 類型,你可以用它來定義外觀。如果你希望進(jìn)一步自定義錯誤信息的顯示,你可以迭代它們來實現(xiàn):

{% if form.subject.errors %}
    <ol>
    {% for error in form.subject.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ol>
{% endif %}

空字段錯誤(以及使用form.as_p() 時渲染的隱藏字段錯誤)將渲染成一個額外的CSS 類型nonfield 以幫助區(qū)分每個字段的錯誤信息。例如,{{ form.non_field_errors }} 看上去會像:

<ul class="errorlist nonfield">
    <li>Generic validation error</li>
</ul>
Changed in Django 1.8:

添加上面示例中提到的nonfield CSS 類型。

參見Forms API 以獲得關(guān)于錯誤、樣式以及在模板中使用表單屬性的更多內(nèi)容。

迭代表單的字段

如果你為你的表單使用相同的HTML,你可以使用{% for %} 循環(huán)迭代每個字段來減少重復(fù)的代碼:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

{{ field }} 中有用的屬性包括:

{{ field.label }}

字段的label,例如Email address。

{{ field.label_tag }}

包含在HTML <label> 標(biāo)簽中的字段Label。它包含表單的label_suffix。例如,默認(rèn)的label_suffix 是一個冒號:

<label for="id_email">Email address:</label>

{{ field.id_for_label }}

用于這個字段的ID(在上面的例子中是id_email)。如果你正在手工構(gòu)造label,你可能想使用它代替label_tag。如果你有一些內(nèi)嵌的JavaScript 并且想避免硬編碼字段的ID,這也是有用的。

{{ field.value }}

字段的值,例如someone@example.com。

{{ field.html_name }}

輸入元素的name 屬性中將使用的名稱。它將考慮到表單的前綴。

{{ field.help_text }}

與該字段關(guān)聯(lián)的幫助文檔。

{{ field.errors }}

輸出一個<ul class="errorlist">,包含這個字段的驗證錯誤信息。你可以使用{% for error in field.errors %}自定義錯誤的顯示。 這種情況下,循環(huán)中的每個對象只是一個包含錯誤信息的簡單字符串。

{{ field.is_hidden }}

如果字段是隱藏字段,則為True,否則為False。作為模板變量,它不是很有用處,但是可以用于條件測試,例如:

{% if field.is_hidden %}

{% endif %}

{{ field.field }}

表單類中的Field 實例,通過BoundField 封裝。你可以使用它來訪問Field 屬性,例如{% char_field.field.max_length %}。

迭代隱藏和可見的字段

如果你正在手工布局模板中的一個表單,而不是依賴Django 默認(rèn)的表單布局,你可能希望將<input type="hidden"> 字段與非隱藏的字段區(qū)別對待。例如,因為隱藏的字段不會顯示,在該字段旁邊放置錯誤信息可能讓你的用戶感到困惑 —— 所以這些字段的錯誤應(yīng)該有區(qū)別地來處理。

Django 提供兩個表單方法,它們允許你獨立地在隱藏的和可見的字段上迭代:hidden_fields()visible_fields()。下面是使用這兩個方法對前面一個例子的修改:

{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}

{% for field in form.visible_fields %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

這個示例沒有處理隱藏字段中的任何錯誤信息。通常,隱藏字段中的錯誤意味著表單被篡改,因為正常的表單填寫不會改變它們。然而,你也可以很容易地為這些表單錯誤插入一些錯誤信息顯示出來。

可重用的表單模板

如果你的網(wǎng)站在多個地方對表單使用相同的渲染邏輯,你可以保存表單的循環(huán)到一個單獨的模板中來減少重復(fù),然后在其它模板中使用include 標(biāo)簽來重用它:

# 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 標(biāo)簽的with 參數(shù)來對它起個別名:

{% include "form_snippet.html" with form=comment_form %}

如果你發(fā)現(xiàn)自己經(jīng)常這樣做,你可能需要考慮一下創(chuàng)建一個自定義的inclusion標(biāo)簽。

更深入的主題

這里只是基礎(chǔ),表單還可以完成更多的工作:

另見

表單參考 覆蓋完整的API 參考,包括表單字段、表單Widget 以及表單和字段的驗證。

譯者:Django 文檔協(xié)作翻譯小組,原文:Overview

本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請保留作者署名和文章出處。

Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。