1. 程式人生 > >二、表單Form物件的使用及構建複雜的QuerySet

二、表單Form物件的使用及構建複雜的QuerySet

  1. Form 可構建標準的表單
  2. ModelForm 可構建與模型例項相關聯的表單

1. 標準表單Form

首先 在應用程式目錄中建立 forms.py 檔案,程式碼如下:

from django import forms

class EmailPostForm(forms.Form):
    name = forms.CharField(max_length=25)
    email = forms.EmailField()
    to = forms.EmailField()
    comments = forms.CharField(required=False, widget=forms.Textarea)
  • CharField 該欄位型別顯示為 <input type="text">
  • widget 為欄位所使用的外掛,在 comments 欄位中使用了 Textarea 外掛
  • EmailField 需要使用有效的電子郵件地址;否則,欄位驗證將丟擲 forms.ValidationError 異常
  • required 表示該欄位是否必填項

有效的表單欄位列表請參照:點選此處

接下來views.py 中使用 Form 表單物件

from .forms import EmailPostForm

def post_share(request, post_id):
    post = get_object_or_404(Post, id=post_id, status='published')
    if request.method == 'POST':
        form = EmailPostForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            # ...
    else:
        form = EmailPostForm()
    return render(request, 'blog/post/share.html', {'post': post, 'form': form})

上述檢視工作方式如下:

  • 定義了 post_share 檢視,並接收 request 物件和 post_id 變數作為引數
  • 採用 get_object_or_404 快捷方式,並通過 ID 檢索帖子,以確保檢索的狀態為 published
  • 根據 request.method == 'POST' 方法區分 POST 請求還是 GET 請求

表單處理流程如下:

  1. 當檢視為 GET 請求時,建立一個新的 form 例項,並用於顯示模板中的空表單: form = EmailPostForm()
  2. 當為 POST 請求時,通過包含於 request.POST 中的提交資料生成一個表單例項:form = EmailPostForm(request.POST)
  3. 利用表單 is_valid() 方法驗證所提交的資料。如果作一欄位包含了無效資料,將返回 False。通過訪問 form.errors 可檢視驗證錯誤列表
  4. 若表單正確,通過訪問 form.cleaned_data 將對驗證後的資料進行檢索。該屬性表示為表單欄位及其對應值的字典。

最後 在檢視中使用 Form 物件:

{% extends "blog/base.html" %}

{% block title %}Share a post{% endblock %}

{% block content %}
    {% if sent %}
        <h1>E-mail successfully sent</h1>
        <p>
            "{{ post.title }}" was successfully sent to {{ form.cleaned_data.to }}.
        </p>
    {% else %}
        <h1>Share "{{ post.title }}" by e-mail</h1>
        <form action="." method="post">
            {{ form.as_p }}
            {% csrf_token %}
            <input type="submit" value="Send e-mail">
        </form>
    {% endif %}
{% endblock %}

此處通知Django利用 as_p 方法將欄位顯示為 <p> 中的欄位。除此之外,還可利用 as_ul 作為無序列表顯示錶單;或者利用 as_table 作為表予以顯示。如果需要顯示每個欄位,可遍歷相關欄位,如下所示:

{% for field in form%}
<div>
 {{ field.errors }}
 {{ field.label_tag }} {{ field }}
</div>
{