<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 表單 API 關于這篇文檔 這篇文檔講述Django 表單API 的詳細細節。你應該先閱讀[_表單簡介_](../../topics/forms/index.html)。 ## 綁定的表單和未綁定的表單 [`表單`](#django.forms.Form "django.forms.Form")要么是**綁定的**,要么是**未綁定的**。 * 如果是**綁定的**,那么它能夠驗證數據,并渲染表單及其數據成HTML。 * 如果是**未綁定的**,那么它不能夠完成驗證(因為沒有可驗證的數據!),但是仍然能渲染空白的表單成HTML。 _class _`Form` 若要創建一個未綁定的[`表單`](#django.forms.Form "django.forms.Form")實例,只需簡單地實例化該類: ``` >>> f = ContactForm() ``` 若要綁定數據到表單,可以將數據以字典的形式傳遞給[`表單`](#django.forms.Form "django.forms.Form")類的構造函數的第一個參數: ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data) ``` 在這個字典中,鍵為字段的名稱,它們對應于[`表單`](#django.forms.Form "django.forms.Form")類中的屬性。值為需要驗證的數據。它們通常為字符串,但是沒有強制要求必須是字符串;傳遞的數據類型取決于[`字段`](fields.html#django.forms.Field "django.forms.Field"),我們稍后會看到。 `Form.``is_bound` 如果運行時刻你需要區分綁定的表單和未綁定的表單,可以檢查下表單[`is_bound`](#django.forms.Form.is_bound "django.forms.Form.is_bound") 屬性的值: ``` >>> f = ContactForm() >>> f.is_bound False >>> f = ContactForm({'subject': 'hello'}) >>> f.is_bound True ``` 注意,傳遞一個空的字典將創建一個帶有空數據的_綁定的_表單: ``` >>> f = ContactForm({}) >>> f.is_bound True ``` 如果你有一個綁定的[`表單`](#django.forms.Form "django.forms.Form")實例但是想改下數據,或者你想綁定一個未綁定的[`表單`](#django.forms.Form "django.forms.Form")表單到某些數據,你需要創建另外一個[`表單`](#django.forms.Form "django.forms.Form")實例。[`Form`](#django.forms.Form "django.forms.Form") 實例的數據沒有辦法修改。[`表單`](#django.forms.Form "django.forms.Form")實例一旦創建,你應該將它的數據視為不可變的,無論它有沒有數據。 ## 使用表單來驗證數據 `Form.``clean`() 當你需要為相互依賴的字段添加自定義的驗證時,你可以實現`表單`的`clean()`方法。示例用法參見[_Cleaning and validating fields that depend on each other_](validation.html#validating-fields-with-clean)。 `Form.``is_valid`() [`表單`](#django.forms.Form "django.forms.Form")對象的首要任務就是驗證數據。對于綁定的[`表單`](#django.forms.Form "django.forms.Form")實例,可以調用[`is_valid()`](#django.forms.Form.is_valid "django.forms.Form.is_valid")方法來執行驗證并返回一個表示數據是否合法的布爾值。 ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data) >>> f.is_valid() True ``` 讓我們試下非法的數據。下面的情形中,`subject` 為空(默認所有字段都是必需的)且`sender` 是一個不合法的郵件地址: ``` >>> data = {'subject': '', ... 'message': 'Hi there', ... 'sender': 'invalid email address', ... 'cc_myself': True} >>> f = ContactForm(data) >>> f.is_valid() False ``` `Form.``errors` 訪問[`errors`](#django.forms.Form.errors "django.forms.Form.errors") 屬性可以獲得錯誤信息的一個字典: ``` >>> f.errors {'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']} ``` 在這個字典中,鍵為字段的名稱,值為表示錯誤信息的Unicode 字符串組成的列表。錯誤信息保存在列表中是因為字段可能有多個錯誤信息。 你可以在調用[`is_valid()`](#django.forms.Form.is_valid "django.forms.Form.is_valid")&nbsp;之前訪問[`errors`](#django.forms.Form.errors "django.forms.Form.errors")。表單的數據將在第一次調用[`is_valid()`](#django.forms.Form.is_valid "django.forms.Form.is_valid") 或者訪問[`errors`](#django.forms.Form.errors "django.forms.Form.errors") 時驗證。 驗證將值調用一次,無論你訪問[`errors`](#django.forms.Form.errors "django.forms.Form.errors") 或者調用[`is_valid()`](#django.forms.Form.is_valid "django.forms.Form.is_valid") 多少次。這意味著,如果驗證過程有副作用,這些副作用將只觸發一次。 `Form.errors.``as_data`() New in Django 1.7\. 返回一個`字典`,它映射字段到原始的`ValidationError` 實例。 ``` >>> f.errors.as_data() {'sender': [ValidationError(['Enter a valid email address.'])], 'subject': [ValidationError(['This field is required.'])]} ``` 每當你需要根據錯誤的`code` 來識別錯誤時,可以調用這個方法。它可以用來重寫錯誤信息或者根據特定的錯誤編寫自定義的邏輯。它還可以用來序列化錯誤為一個自定義的格式(例如,XML);[`as_json()`](#django.forms.Form.errors.as_json "django.forms.Form.errors.as_json") 就依賴于`as_data()`。 需要`as_data()` 方法是為了向后兼容。以前,`ValidationError` 實例在它們**渲染后**&nbsp;的錯誤消息一旦添加到`Form.errors` 字典就立即被丟棄。理想情況下,`Form.errors` 應該已經保存`ValidationError` 實例而帶有`as_` 前綴的方法可以渲染它們,但是為了不破壞直接使用`Form.errors` 中的錯誤消息的代碼,必須使用其它方法來實現。 `Form.errors.``as_json`(_escape_html=False_) New in Django 1.7\. 返回JSON 序列化后的錯誤。 ``` >>> f.errors.as_json() {"sender": [{"message": "Enter a valid email address.", "code": "invalid"}], "subject": [{"message": "This field is required.", "code": "required"}]} ``` 默認情況下,`as_json()` 不會轉義它的輸出。如果你正在使用AJAX 請求表單視圖,而客戶端會解析響應并將錯誤插入到頁面中,你必須在客戶端對結果進行轉義以避免可能的跨站腳本攻擊。使用一個JavaScript 庫比如jQuery 來做這件事很簡單 —— 只要使用`$(el).text(errorText)` 而不是`.html()` 就可以。 如果由于某種原因你不想使用客戶端的轉義,你還可以設置`escape_html=True`,這樣錯誤消息將被轉義而你可以直接在HTML 中使用它們。 `Form.``add_error`(_field_, _error_) New in Django 1.7\. 這個方法允許在`Form.clean()` 方法內部或從表單的外部一起給字段添加錯誤信息;例如從一個視圖中。 `field` 參數為字段的名稱。如果值為`None`,error 將作為[`Form.non_field_errors()`](#django.forms.Form.non_field_errors "django.forms.Form.non_field_errors") 返回的一個非字段錯誤。 `error` 參數可以是一個簡單的字符串,或者最好是一個`ValidationError` 實例。[_引發ValidationError_](validation.html#raising-validation-error) 中可以看到定義表單錯誤時的最佳實踐。 注意,`Form.add_error()` 會自動刪除`cleaned_data` 中的相關字段。 `Form.``has_error`(_field_, _code=None_) New in Django 1.8\. 這個方法返回一個布爾值,指示一個字段是否具有指定錯誤`code` 的錯誤。當`code` 為`None` 時,如果字段有任何錯誤它都將返回`True`。 若要檢查非字段錯誤,使用[`NON_FIELD_ERRORS`](../exceptions.html#django.core.exceptions.NON_FIELD_ERRORS "django.core.exceptions.NON_FIELD_ERRORS") 作為`field` 參數。 `Form.``non_field_errors`() 這個方法返回[`Form.errors`](#django.forms.Form.errors "django.forms.Form.errors") 中不是與特定字段相關聯的錯誤。它包含在[`Form.clean()`](#django.forms.Form.clean "django.forms.Form.clean") 中引發的`ValidationError` 和使用[`Form.add_error(None, "...")`](#django.forms.Form.add_error "django.forms.Form.add_error") 添加的錯誤。 ### 未綁定表單的行為 驗證沒有綁定數據的表單是沒有意義的,下面的例子展示了這種情況: ``` >>> f = ContactForm() >>> f.is_valid() False >>> f.errors {} ``` ## 動態的初始值 `Form.``initial` 表單字段的初始值使用[`initial`](#django.forms.Form.initial "django.forms.Form.initial")聲明。例如,你可能希望使用當前會話的用戶名填充`username`字段。 使用[`Form`](#django.forms.Form "django.forms.Form")的[`initial`](#django.forms.Form.initial "django.forms.Form.initial")參數可以實現。該參數是字段名到初始值的一個字典。只需要包含你期望給出初始值的字段;不需要包含表單中的所有字段。例如: ``` >>> f = ContactForm(initial={'subject': 'Hi there!'}) ``` 這些值只顯示在沒有綁定的表單中,即使沒有提供特定值它們也不會作為后備的值。 注意,如果[`字段`](fields.html#django.forms.Field "django.forms.Field")有定義[`initial`](#django.forms.Form.initial "django.forms.Form.initial"), _而_實例化`表單`時也提供`initial`,那么后面的`initial` 將優先。在下面的例子中,`initial` 在字段和表單實例化中都有定義,此時后者具有優先權: ``` >>> from django import forms >>> class CommentForm(forms.Form): ... name = forms.CharField(initial='class') ... url = forms.URLField() ... comment = forms.CharField() >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False) >>> print(f) <tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr> <tr><th>Url:</th><td><input type="url" name="url" /></td></tr> <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr> ``` ## 檢查表單數據是否改變 `Form.``has_changed`() 當你需要檢查表單的數據是否從初始數據發生改變時,可以使用`表單`的`has_changed()` 方法。 ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data, initial=data) >>> f.has_changed() False ``` 當提交表單時,我們可以重新構建表單并提供初始值,這樣可以實現比較: ``` >>> f = ContactForm(request.POST, initial=data) >>> f.has_changed() ``` 如果`request.POST` 中的數據與[`initial`](#django.forms.Form.initial "django.forms.Form.initial") 中的不同,`has_changed()` 將為`True`,否則為`False`。 計算的結果是通過調用表單每個字段的[`Field.has_changed()`](fields.html#django.forms.Field.has_changed "django.forms.Field.has_changed") 得到的。 ## 從表單中訪問字段 `Form.``fields` 你可以從[`表單`](#django.forms.Form "django.forms.Form")實例的`fields`屬性訪問字段: ``` >>> for row in f.fields.values(): print(row) ... <django.forms.fields.CharField object at 0x7ffaac632510> <django.forms.fields.URLField object at 0x7ffaac632f90> <django.forms.fields.CharField object at 0x7ffaac3aa050> >>> f.fields['name'] <django.forms.fields.CharField object at 0x7ffaac6324d0> ``` 可你可以修改[`表單`](#django.forms.Form "django.forms.Form")實例的字段來改變字段在表單中的表示: ``` >>> f.as_table().split('\n')[0] '<tr><th>Name:</th><td><input name="name" type="text" value="instance" /></td></tr>' >>> f.fields['name'].label = "Username" >>> f.as_table().split('\n')[0] '<tr><th>Username:</th><td><input name="name" type="text" value="instance" /></td></tr>' ``` 注意不要改變`base_fields` 屬性,因為一旦修改將影響同一個Python 進程中接下來所有的`ContactForm` 實例: ``` >>> f.base_fields['name'].label = "Username" >>> another_f = CommentForm(auto_id=False) >>> another_f.as_table().split('\n')[0] '<tr><th>Username:</th><td><input name="name" type="text" value="class" /></td></tr>' ``` ## 訪問“清潔”的數據 `Form.``cleaned_data` [`表單`](#django.forms.Form "django.forms.Form")類中的每個字段不僅負責驗證數據,還負責“清潔”它們 —— 將它們轉換為正確的格式。這是個非常好用的功能,因為它允許字段以多種方式輸入數據,并總能得到一致的輸出。 例如,[`DateField`](fields.html#django.forms.DateField "django.forms.DateField") 將輸入轉換為Python 的 `datetime.date` 對象。無論你傳遞的是`'1994-07-15'` 格式的字符串、`datetime.date` 對象、還是其它格式的數字,`DateField` 將始終將它們轉換成`datetime.date` 對象,只要它們是合法的。 一旦你創建一個[`表單`](#django.forms.Form "django.forms.Form")實例并通過驗證后,你就可以通過它的`cleaned_data` 屬性訪問清潔的數據: ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data) >>> f.is_valid() True >>> f.cleaned_data {'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'} ``` 注意,文本字段 —— 例如,`CharField` 和`EmailField` —— 始終將輸入轉換為Unicode 字符串。我們將在這篇文檔的后面將是編碼的影響。 如果你的數據_沒有_ 通過驗證,`cleaned_data` 字典中只包含合法的字段: ``` >>> data = {'subject': '', ... 'message': 'Hi there', ... 'sender': 'invalid email address', ... 'cc_myself': True} >>> f = ContactForm(data) >>> f.is_valid() False >>> f.cleaned_data {'cc_myself': True, 'message': 'Hi there'} ``` `cleaned_data` 始終_只_ 包含`表單`中定義的字段,即使你在構建`表單` 時傳遞了額外的數據。在下面的例子中,我們傳遞一組額外的字段給`ContactForm` 構造函數,但是`cleaned_data` 將只包含表單的字段: ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True, ... 'extra_field_1': 'foo', ... 'extra_field_2': 'bar', ... 'extra_field_3': 'baz'} >>> f = ContactForm(data) >>> f.is_valid() True >>> f.cleaned_data # Doesn't contain extra_field_1, etc. {'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'} ``` 當`表單`合法時,`cleaned_data` 將包含_所有_字段的鍵和值,即使傳遞的數據不包含某些可選字段的值。在下面的例子中,傳遞的數據字典不包含`nick_name` 字段的值,但是`cleaned_data` 任然包含它,只是值為空: ``` >>> from django.forms import Form >>> class OptionalPersonForm(Form): ... first_name = CharField() ... last_name = CharField() ... nick_name = CharField(required=False) >>> data = {'first_name': 'John', 'last_name': 'Lennon'} >>> f = OptionalPersonForm(data) >>> f.is_valid() True >>> f.cleaned_data {'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'} ``` 在上面的例子中,`cleaned_data` 中`nick_name` 設置為一個空字符串,這是因為`nick_name` 是`CharField`而 `CharField` 將空值作為一個空字符串。每個字段都知道自己的“空”值 —— 例如,`DateField` 的空值是`None` 而不是一個空字符串。關于每個字段空值的完整細節,參見“內建的`Field` 類”一節中每個字段的“空值”提示。 你可以自己編寫代碼來對特定的字段(根據它們的名字)或者表單整體(考慮到不同字段的組合)進行驗證。更多信息參見[_表單和字段驗證_](validation.html)。 ## 輸出表單為HTML `表單`對象的第二個任務是將它渲染成HTML。很簡單,`print` 它: ``` >>> f = ContactForm() >>> print(f) <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr> <tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr> <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr> ``` 如果表單是綁定的,輸出的HTML 將包含數據。例如,如果字段是`<input type="text">` 的形式,其數據將位于`value` 屬性中。如果字段是`<input type="checkbox">` 的形式,HTML 將包含`checked="checked"`: ``` >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data) >>> print(f) <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr> <tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" value="foo@example.com" /></td></tr> <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr> ``` 默認的輸出時具有兩個列的HTML 表格,每個字段對應一個`<tr>`。注意事項: * 為了靈活性,輸出_不_包含`<table>` 和`</table>`、`<form>` 和`</form>`&nbsp;以及`<input type="submit">` 標簽。你需要添加它們。 * 每個字段類型有一個默認的HTML 表示。`CharField` 表示為一個`<input type="text">`,`EmailField` 表示為一個`<input type="email">`。`BooleanField` 表示為一個`<input type="checkbox">`。注意,這些只是默認的表示;你可以使用Widget 指定字段使用哪種HTML,我們將稍后解釋。 * 每個標簽的HTML `name` 直接從`ContactForm` 類中獲取。 * 每個字段的文本標簽 —— 例如`'Subject:'`、`'Message:'` 和`'Cc myself:'` 通過將所有的下劃線轉換成空格并大寫第一個字母生成。再次提醒,這些只是默認的表示;你可以手工指定標簽。 * 每個文本標簽周圍有一個HTML `<label>` 標簽,它指向表單字段的`id`。這個`id`,是通過在字段名稱前面加上`'id_'` 前綴生成。`id` 屬性和`<label>` 標簽默認包含在輸出中,但你可以改變這一行為。 雖然`print` 表單時`<table>` 是默認的輸出格式,但是還有其它格式可用。每個格式對應于表單對象的一個方法,每個方法都返回一個Unicode 對象。 ### as_p() `Form.``as_p`() `as_p()` 渲染表單為一系列的`<p>` 標簽,每個`<p>` 標簽包含一個字段: ``` >>> f = ContactForm() >>> f.as_p() '<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>' >>> print(f.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> ``` ### as_ul() `Form.``as_ul`() `as_ul()` 渲染表單為一系列的`<li>`標簽,每個`<li>` 標簽包含一個字段。它_不_包含`<ul>` 和`</ul>`,所以你可以自己指定`<ul>` 的任何HTML 屬性: ``` >>> f = ContactForm() >>> f.as_ul() '<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>' >>> print(f.as_ul()) <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li> <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li> <li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" /></li> <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li> ``` ### as_table() `Form.``as_table`() 最后,`as_table()`輸出表單為一個HTML `<table>`。它與`print` 完全相同。事實上,當你`print` 一個表單對象時,在后臺調用的就是`as_table()` 方法: ``` >>> f = ContactForm() >>> f.as_table() '<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>' >>> print(f.as_table()) <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr> <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr> <tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr> <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr> ``` ### 表單必填行和錯誤行的樣式 `Form.``error_css_class` `Form.``required_css_class` 將必填的表單行和有錯誤的表單行定義不同的樣式特別常見。例如,你想將必填的表單行以粗體顯示、將錯誤以紅色顯示。 [`表單`](#django.forms.Form "django.forms.Form")類具有一對鉤子,可以使用它們來添加`class` 屬性給必填的行或有錯誤的行:只需簡單地設置[`Form.error_css_class`](#django.forms.Form.error_css_class "django.forms.Form.error_css_class") 和/或 [`Form.required_css_class`](#django.forms.Form.required_css_class "django.forms.Form.required_css_class") 屬性: ``` from django.forms import Form class ContactForm(Form): error_css_class = 'error' required_css_class = 'required' # ... and the rest of your fields here ``` 一旦你設置好,將根據需要設置行的`"error"` 和/或`"required"` CSS 類型。 其HTML 看上去將類似: ``` >>> f = ContactForm(data) >>> print(f.as_table()) <tr class="required"><th><label class="required" for="id_subject">Subject:</label> ... <tr class="required"><th><label class="required" for="id_message">Message:</label> ... <tr class="required error"><th><label class="required" for="id_sender">Sender:</label> ... <tr><th><label for="id_cc_myself">Cc myself:<label> ... >>> f['subject'].label_tag() <label class="required" for="id_subject">Subject:</label> >>> f['subject'].label_tag(attrs={'class': 'foo'}) <label for="id_subject" class="foo required">Subject:</label> ``` Changed in Django 1.8: `required_css_class` 添加到`<label>` 標簽,如上面所看到的。 ### 配置表單元素的HTML `id` 屬性和 `<label>` 標簽 `Form.``auto_id` 默認情況下,表單的渲染方法包含: * 表單元素的HTML `id` 屬性 * 對應的`<label>` 標簽。HTML `<label>` 標簽指示標簽文本關聯的表單元素。這個小小的改進讓表單在輔助設備上具有更高的可用性。使用`<label>` 標簽始終是個好想法。 `id` 屬性值通過在表單字段名稱的前面加上`id_` 生成。但是如果你想改變`id` 的生成方式或者完全刪除 HTML `id` 屬性和`<label>`標簽,這個行為是可配置的。 `id` 和label 的行為使用`表單`構造函數的`auto_id` 參數控制。這個參數必須為`True`、`False` 或者一個字符串。 如果`auto_id` 為`False`,那么表單的輸出將不包含`<label>` 標簽和`id` 屬性: ``` >>> f = ContactForm(auto_id=False) >>> print(f.as_table()) <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr> <tr><th>Message:</th><td><input type="text" name="message" /></td></tr> <tr><th>Sender:</th><td><input type="email" name="sender" /></td></tr> <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr> >>> print(f.as_ul()) <li>Subject: <input type="text" name="subject" maxlength="100" /></li> <li>Message: <input type="text" name="message" /></li> <li>Sender: <input type="email" name="sender" /></li> <li>Cc myself: <input type="checkbox" name="cc_myself" /></li> >>> print(f.as_p()) <p>Subject: <input type="text" name="subject" maxlength="100" /></p> <p>Message: <input type="text" name="message" /></p> <p>Sender: <input type="email" name="sender" /></p> <p>Cc myself: <input type="checkbox" name="cc_myself" /></p> ``` 如果`auto_id` 設置為`True`,那么輸出的表示_將_ 包含`<label>` 標簽并簡單地使用字典名稱作為每個表單字段的`id`: ``` >>> f = ContactForm(auto_id=True) >>> print(f.as_table()) <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr> <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr> <tr><th><label for="sender">Sender:</label></th><td><input type="email" name="sender" id="sender" /></td></tr> <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr> >>> print(f.as_ul()) <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li> <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li> <li><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" /></li> <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li> >>> print(f.as_p()) <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p> <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p> <p><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" /></p> <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p> ``` 如果`auto_id` 設置為包含格式字符`'%s'` 的字符串,那么表單的輸出將包含`<label>` 標簽,并將根據格式字符串生成`id` 屬性。例如,對于格式字符串`'field_%s'`,名為`subject` 的字段的`id` 值將是`'field_subject'`。繼續我們的例子: ``` >>> f = ContactForm(auto_id='id_for_%s') >>> print(f.as_table()) <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr> <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr> <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="email" name="sender" id="id_for_sender" /></td></tr> <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr> >>> print(f.as_ul()) <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li> <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li> <li><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" /></li> <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li> >>> print(f.as_p()) <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p> <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p> <p><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" /></p> <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p> ``` 如果`auto_id` 設置為任何其它的真值 —— 例如不包含`%s` 的字符串 —— 那么其行為將類似`auto_id` 等于`True`。 默認情況下,`auto_id` 設置為`'id_%s'`。 `Form.``label_suffix` 一個字符串(默認為英文的`:`),表單渲染時將附加在每個label 名稱的后面。 使用`label_suffix` 參數可以自定義這個字符,或者完全刪除它: ``` >>> f = ContactForm(auto_id='id_for_%s', label_suffix='') >>> print(f.as_ul()) <li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li> <li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" /></li> <li><label for="id_for_sender">Sender</label> <input type="email" name="sender" id="id_for_sender" /></li> <li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li> >>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->') >>> print(f.as_ul()) <li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li> <li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" /></li> <li><label for="id_for_sender">Sender -></label> <input type="email" name="sender" id="id_for_sender" /></li> <li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li> ``` 注意,該標簽后綴只有當label 的最后一個字符不是表單符號(`.`, `!`, `?` 和`:`)時才添加。 New in Django 1.8\. 字段可以定義自己的[`label_suffix`](fields.html#django.forms.Field.label_suffix "django.forms.Field.label_suffix")。而且將優先于[`Form.label_suffix`](#django.forms.Form.label_suffix "django.forms.Form.label_suffix")。在運行時刻,后綴可以使用[`label_tag()`](#django.forms.BoundField.label_tag "django.forms.BoundField.label_tag") 的`label_suffix` 參數覆蓋。 ### 字段的順序 在`as_p()`、`as_ul()` 和`as_table()` 中,字段以表單類中定義的順序顯示。例如,在`ContactForm` 示例中,字段定義的順序為`subject`, `message`, `sender`, `cc_myself`。若要重新排序HTML 中的輸出,只需改變字段在類中列出的順序。 ### 錯誤如何顯示 如果你渲染一個綁定的`表單`對象,渲染時將自動運行表單的驗證,HTML 輸出將在出錯字段的附近以`<ul class="errorlist">` 形式包含驗證的錯誤。錯誤信息的位置與你使用的輸出方法有關: ``` >>> data = {'subject': '', ... 'message': 'Hi there', ... 'sender': 'invalid email address', ... 'cc_myself': True} >>> f = ContactForm(data, auto_id=False) >>> print(f.as_table()) <tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr> <tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr> <tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid email address.</li></ul><input type="email" name="sender" value="invalid email address" /></td></tr> <tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr> >>> print(f.as_ul()) <li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li> <li>Message: <input type="text" name="message" value="Hi there" /></li> <li><ul class="errorlist"><li>Enter a valid email address.</li></ul>Sender: <input type="email" name="sender" value="invalid email address" /></li> <li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li> >>> print(f.as_p()) <p><ul class="errorlist"><li>This field is required.</li></ul></p> <p>Subject: <input type="text" name="subject" maxlength="100" /></p> <p>Message: <input type="text" name="message" value="Hi there" /></p> <p><ul class="errorlist"><li>Enter a valid email address.</li></ul></p> <p>Sender: <input type="email" name="sender" value="invalid email address" /></p> <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> ``` ### 自定義錯誤清單的格式 默認情況下,表單使用`django.forms.utils.ErrorList` 來格式化驗證時的錯誤。如果你希望使用另外一種類來顯示錯誤,可以在構造時傳遞(在Python 2 中將 `__str__` 替換為`__unicode__`): ``` >>> from django.forms.utils import ErrorList >>> class DivErrorList(ErrorList): ... def __str__(self): # __unicode__ on Python 2 ... return self.as_divs() ... def as_divs(self): ... if not self: return '' ... return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % e for e in self]) >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) >>> f.as_p() <div class="errorlist"><div class="error">This field is required.</div></div> <p>Subject: <input type="text" name="subject" maxlength="100" /></p> <p>Message: <input type="text" name="message" value="Hi there" /></p> <div class="errorlist"><div class="error">Enter a valid email address.</div></div> <p>Sender: <input type="email" name="sender" value="invalid email address" /></p> <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> ``` Changed in Django 1.7: `django.forms.util` 重命名為`django.forms.utils`。 ### 更細粒度的輸出 `as_p()`、`as_ul()` 和`as_table()` 方法是為懶惰的程序員準備的簡單快捷方法 —— 它們不是顯示表單的唯一方式。 _class _`BoundField` 用于顯示HTML 表單或者訪問[`表單`](#django.forms.Form "django.forms.Form")實例的一個屬性。 其`__str__()`(Python 2 上為`__unicode__`)方法顯示該字段的HTML。 以字段的名稱為鍵,用字典查詢語法查詢表單,可以獲取一個 `BoundField`: ``` >>> form = ContactForm() >>> print(form['subject']) <input id="id_subject" type="text" name="subject" maxlength="100" /> ``` 迭代表單可以獲取所有的`BoundField`: ``` >>> form = ContactForm() >>> for boundfield in form: print(boundfield) <input id="id_subject" type="text" name="subject" maxlength="100" /> <input type="text" name="message" id="id_message" /> <input type="email" name="sender" id="id_sender" /> <input type="checkbox" name="cc_myself" id="id_cc_myself" /> ``` 字段的輸出與表單的`auto_id` 設置有關: ``` >>> f = ContactForm(auto_id=False) >>> print(f['message']) <input type="text" name="message" /> >>> f = ContactForm(auto_id='id_%s') >>> print(f['message']) <input type="text" name="message" id="id_message" /> ``` 若要獲取字段的錯誤列表,可以訪問字段的`errors` 屬性。 `BoundField.``errors` 一個類列表對象,打印時以HTML `<ul class="errorlist">` 形式顯示: ``` >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''} >>> f = ContactForm(data, auto_id=False) >>> print(f['message']) <input type="text" name="message" /> >>> f['message'].errors ['This field is required.'] >>> print(f['message'].errors) <ul class="errorlist"><li>This field is required.</li></ul> >>> f['subject'].errors [] >>> print(f['subject'].errors) >>> str(f['subject'].errors) '' ``` `BoundField.``label_tag`(_contents=None_, _attrs=None_, _label_suffix=None_) 可以調用`label_tag` 方法單獨渲染表單字段的label 標簽: ``` >>> f = ContactForm(data) >>> print(f['message'].label_tag()) <label for="id_message">Message:</label> ``` 如果你提供一個可選的`contents` 參數,它將替換自動生成的label 標簽。另外一個可選的`attrs` &nbsp;參數可以包含`<label>` 標簽額外的屬性。 生成的HTML 包含表單的[`label_suffix`](#django.forms.Form.label_suffix "django.forms.Form.label_suffix")(默認為一個冒號),或者當前字段的[`label_suffix`](fields.html#django.forms.Field.label_suffix "django.forms.Field.label_suffix")。可選的`label_suffix` 參數允許你覆蓋之前設置的后綴。例如,你可以使用一個空字符串來隱藏已選擇字段的label。如果在模板中需要這樣做,你可以編寫一個自定義的過濾器來允許傳遞參數給`label_tag`。 Changed in Django 1.8: 如果可用,label 將包含[`required_css_class`](#django.forms.Form.required_css_class "django.forms.Form.required_css_class")。 `BoundField.``css_classes`() 當你使用Django 的快捷的渲染方法時,習慣使用CSS &nbsp;類型來表示必填的表單字段和有錯誤的字段。如果你是手工渲染一個表單,你可以使用`css_classes` 方法訪問這些CSS 類型: ``` >>> f = ContactForm(data) >>> f['message'].css_classes() 'required' ``` 除了錯誤和必填的類型之外,如果你還想提供額外的類型,你可以用參數傳遞它們: ``` >>> f = ContactForm(data) >>> f['message'].css_classes('foo bar') 'foo bar required' ``` `BoundField.``value`() 這個方法用于渲染字段的原始值,與用`Widget` 渲染的值相同: ``` >>> initial = {'subject': 'welcome'} >>> unbound_form = ContactForm(initial=initial) >>> bound_form = ContactForm(data, initial=initial) >>> print(unbound_form['subject'].value()) welcome >>> print(bound_form['subject'].value()) hi ``` `BoundField.``id_for_label` 使用這個屬性渲染字段的ID。例如,如果你在模板中手工構造一個`<label>`(盡管 [`label_tag()`](#django.forms.BoundField.label_tag "django.forms.BoundField.label_tag") 將為你這么做): ``` <label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }} ``` 默認情況下,它是在字段名稱的前面加上`id_` (上面的例子中將是“`id_my_field`”)。你可以通過設置字段Widget 的[`attrs`](widgets.html#django.forms.Widget.attrs "django.forms.Widget.attrs") 來修改ID。例如,像這樣聲明一個字段: ``` my_field = forms.CharField(widget=forms.TextInput(attrs={'id': 'myFIELD'})) ``` 使用上面的模板,將渲染成: ``` <label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" /> ``` ## 綁定上傳的文件到表單 處理帶有`FileField` 和`ImageField` 字段的表單比普通的表單要稍微復雜一點。 首先,為了上傳文件,你需要確保你的`<form>` 元素正確定義`enctype` 為`"multipart/form-data"`: ``` <form enctype="multipart/form-data" method="post" action="/foo/"> ``` 其次,當你使用表單時,你需要綁定文件數據。文件數據的處理與普通的表單數據是分開的,所以如果表單包含`FileField` 和`ImageField`,綁定表單時你需要指定第二個參數。所以,如果我們擴展ContactForm 并包含一個名為`mugshot` 的`ImageField`,我們需要綁定包含mugshot 圖片的文件數據: ``` # Bound form with an image field >>> from django.core.files.uploadedfile import SimpleUploadedFile >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <file data>)} >>> f = ContactFormWithMugshot(data, file_data) ``` 實際上,你一般將使用`request.FILES` 作為文件數據的源(和使用`request.POST` 作為表單數據的源一樣): ``` # Bound form with an image field, data from the request >>> f = ContactFormWithMugshot(request.POST, request.FILES) ``` 構造一個未綁定的表單和往常一樣 —— 將表單數據_和_文件數據同時省略: ``` # Unbound form with an image field >>> f = ContactFormWithMugshot() ``` ### 測試multipart 表單 `Form.``is_multipart`() 如果你正在編寫可重用的視圖或模板,你可能事先不知道你的表單是否是一個multipart 表單。`is_multipart()` 方法告訴你表單提交時是否要求multipart: ``` >>> f = ContactFormWithMugshot() >>> f.is_multipart() True ``` 下面是如何在模板中使用它的一個示例: ``` {% if form.is_multipart %} <form enctype="multipart/form-data" method="post" action="/foo/"> {% else %} <form method="post" action="/foo/"> {% endif %} {{ form }} </form> ``` ## 子類化表單 如果你有多個`表單`類共享相同的字段,你可以使用子類化來減少冗余。 當你子類化一個自定義的`表單`類時,生成的子類將包含父類中的所有字段,以及在子類中定義的字段。 在下面的例子中,`ContactFormWithPriority` 包含`ContactForm` 中的所有字段,以及另外一個字段`priority`。排在前面的是`ContactForm` 中的字段: ``` >>> class ContactFormWithPriority(ContactForm): ... priority = forms.CharField() >>> f = ContactFormWithPriority(auto_id=False) >>> print(f.as_ul()) <li>Subject: <input type="text" name="subject" maxlength="100" /></li> <li>Message: <input type="text" name="message" /></li> <li>Sender: <input type="email" name="sender" /></li> <li>Cc myself: <input type="checkbox" name="cc_myself" /></li> <li>Priority: <input type="text" name="priority" /></li> ``` 可以子類化多個表單,將表單作為“mix-ins”。在下面的例子中,`BeatleForm` 子類化`PersonForm` 和 `InstrumentForm` ,所以它的字段列表包含兩個父類的所有字段: ``` >>> from django.forms import Form >>> class PersonForm(Form): ... first_name = CharField() ... last_name = CharField() >>> class InstrumentForm(Form): ... instrument = CharField() >>> class BeatleForm(PersonForm, InstrumentForm): ... haircut_type = CharField() >>> b = BeatleForm(auto_id=False) >>> print(b.as_ul()) <li>First name: <input type="text" name="first_name" /></li> <li>Last name: <input type="text" name="last_name" /></li> <li>Instrument: <input type="text" name="instrument" /></li> <li>Haircut type: <input type="text" name="haircut_type" /></li> ``` New in Django 1.7\. * 在子類中,可以通過設置名字為`None` 來刪除從父類中繼承的`字段`。例如: ``` >>> from django import forms >>> class ParentForm(forms.Form): ... name = forms.CharField() ... age = forms.IntegerField() >>> class ChildForm(ParentForm): ... name = None >>> ChildForm().fields.keys() ... ['age'] ``` ## 表單前綴 `Form.``prefix` 你可以將幾個Django 表單放在一個`<form>` 標簽中。為了給每個`表單`一個自己的命名空間,可以使用`prefix` 關鍵字參數: ``` >>> mother = PersonForm(prefix="mother") >>> father = PersonForm(prefix="father") >>> print(mother.as_ul()) <li><label for="id_mother-first_name">First name:</label> <input type="text" name="mother-first_name" id="id_mother-first_name" /></li> <li><label for="id_mother-last_name">Last name:</label> <input type="text" name="mother-last_name" id="id_mother-last_name" /></li> >>> print(father.as_ul()) <li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li> <li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li> ``` > 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Form API](https://docs.djangoproject.com/en/1.8/ref/forms/api/)。 > > 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。 > > [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看