Skip to main content

Working with forms

Working with forms

原文链接:http://docs.djangoproject.com/en/dev/topics/forms/#topics-forms-index
翻译:將王車

使用forms

关于本文档

本文档提供对Django form处理的简单介绍,需要更详细的资料请查看The Form API,更多关于可用字段类型的文档请查看:Form fields

django.forms是Django用来进行表单处理的库。

虽然使用Django的HttpRequest类就能处理表单提交的东西,而forms库关注与处理大量form通用的任务。使用它你可以:

  1. 从控件自动生成可显示的HMTL的表单。
  2. 使用一定的规则来验证提交的数据。
  3. 出错后重新显示表单。
  4. 转换提交的数据到相应的Python数据类型。

简介

该库包含一下组件:

  • Widget

    用来处理HMTL表单控件的类,例如:<input type="text"><textarea>。他负责将控件转化为HTML

  • Field

    负责验证的类,例如:EmailField确保它的数据是有效e-mail地址。

  • Form

    字段的集合,它知道如何对自身进行验证和显示为HTML

  • Form Media

    输出表单所需要的CSS和javascript资源。

这个库和数据库层、显示、模板等其它的Diango组件是无关的,仅仅依赖与Django的settings组件、django.utils的帮助函数和Django的国际化钩子(在使用该库的时候没有必要使用国际化属性)。

Form对象

在Form对象内封装了表单的字段和表单必须满足验证规则。Form类是django.forms.Form的子类,并且如果你使用了Django的数据库模型它也能很好的xxxx(are make use of a declarative style that you’ll be familiar with if you’ve used Django’s database models.)。

例如,利用form在一个个人站点上来实现一个“留言薄”的功能:

from django import forms

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

一个表单使用Field对象所组成的,在本例中可以看到我们表单有四个字段:subject, message, sender and cc_myself。CharFieldEmailFieldBooleanField是三种可用的字段类型。更详细的字段列表请看From fields

如果你的表单是直接用来添加和编辑一个Django的模型类,你可以使用ModelForm来避免重复输入。

在视图(View)中使用表单

在视图中处理表单的标准过程如下:

def contact(request):
if request.method == 'POST': # 提交表单
form = ContactForm(request.POST) # 将提交的数据绑定到表单
if form.is_valid(): # 是否通过了所有的验证规则
# 处理form.cleaned_data中的数据
# ...
return HttpResponseRedirect('/thanks/') # 处理以后重定向
else:
form = ContactForm() # An unbound form

return render_to_response('contact.html', {
'form': form,
})

代码有三条处理路径:

  1. 如果并非提交的数据,一个空的表单会被创建并交给模板输出。
  2. 如果是表单提交回来,则根据request.POST创建一个表单对象。如果提交的数据都通过了验证,则处理相关数据并重定向用户到感谢页面。
  3. 如果有数据提交但未通过验证则将该表单交给模板输出。

Django 1.0中的变化:cleaned_data在以前的版本中叫clean_data

boundunbound间的区别是非常重要的。一个unbound的表单不包含任何的数据,当它被输出给用户的时候应当显示为空或是默认值。而一个bound的表单有提交的数据,所以可用来验证数据是否有效。当一个未通过验证的表单被输出给用户的时候将包括提示信息来告诉他们什么地方出错了。

更多关于bound和unbound表单间区别的信息请查看:Bound and unbound forms

处理表单中的数据

一旦is_valid()返回True,你就能放心的处理表单提交的数据,因为他们都通过你表单的验证规则。现在你能直接访问,但更好的选择是访问form.cleaned_data。数据不仅仅是通过了验证,并且能为你转换为相应的Python数据类型。在下面的例子中cc_myself是一个布尔值。同样,IntegerFieldFloatField这些字段分别会被被转换为Python的int和float。

一下例子将示范如何处理表单的数据:

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)

from django.core.mail import send_mail
send_mail(subject, message, sender, recipients)
return HttpResponseRedirect('/thanks/') # Redirect after POST

更到关于在Django中发送邮件的信息请查看Sending e-mail

使用模板显示表单

表单被设计为能同Django的模板语言一起工作。在一下的例子中我们使用变量form来将ContactForm的实例传递到模板。这里是简单的模板示例:

<form action="/contact/" method="post">
{{ form.as_p }}
<input value="Submit" type="submit">
</form>

表单只输出自己的字段,需要你来提供<form>标签和提交按钮。

form.as_p将输出每个字段和相应的标签,并以段落来分割。下面是示例模板的输出:

<form action="/contact/" method="post">
<p><label for="id_subject">Subject:</label>
<input id="id_subject" name="subject" maxlength="100" type="text"></p>
<p><label for="id_message">Message:</label>
<input name="message" id="id_message" type="text"></p>
<p><label for="id_sender">Sender:</label>

<p><label for="id_cc_myself">Cc myself:</label>
<input name="cc_myself" id="id_cc_myself" type="checkbox"></p>

</form>

请注意,表单的每个字段的ID属性都被设为了id_<字段名>,并被相应的标签所引用。这对让表单对屏幕阅读等辅助软件更友好来说是非常重用的。你也能看看customize the way in which labels and ids are generated

你也可以使用form.as_table来输出表格的行(需要自己提供<table>标签)和form.as_ul来输出列表项。

自定义表单模板

如果默认生成的HTML不合你的胃口,你可以使用Django的模板语言来完全自定义表单的呈现方式。示例如下:

<form action="/contact/" method="POST">
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="id_subject">E-mail subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="id_message">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="id_sender">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="id_cc_myself">CC yourself?</label>
{{ form.cc_myself }}
</div>
<p><input type="submit" value="Send message"></p>
</form>

表单的字段都能使用{{ form.name_of_field }}来输出到模板,他将生成显示表单控件所需要的HTML。使用{{ form.name_of_field.errors }}来显示表单中的错误,它将输出个象下面一个的位排序的列表:

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

这个列表有个名为errorlist的CSS类,你可以用来定义它的显示样式。如果你想更近一步的控制错误的显示,也能使用遍历来访问他们:

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

更多的资料

这里只谈到一些基本的东西,但表单所能做的事情远不止如此:


Comments

Popular posts from this blog

欠税了!!!!

上个礼拜,收到政府发来的信,大概知道是和缴税有关的,由于本人英文不好,而且我们缴税的方面一向是由公司负责的,以为是普通的通知。因为同事收到的信都和我的不一样,还是决定带给老大看看是什么东西。结果把老大吓了一跳,红的,居然是红的(我怎么看都只有一点淡淡的红色。)。这意味着我欠税了。在这个资本主义国家,最恐怖的事情莫过去欠税了!!!我的工作准证很可能被吊销。 下午立马跑回公司找人事部的。我居然公司成立几十年来第一个红单。。。人事部的人说还好公司一贯信誉良好,他们会和那边联系,让我先放心。 我倒是很放心,一点都不急。其实我想回家了,和女朋友的关系这几天又到了谷底,想回去了,虽然房子钱还没有着落。

ipod touch

昨天晚上买了iPod Touch 8G S$388,晚上手机没法照,上一张官网的图: 拿在手里的感觉很不错,超薄。终于可以用上传说中的多重触控了。音质?汗,我素木耳。 昨晚太赶,忘了贴膜,配套的套子也没有。今天再去森林看看。这些杂物好贵啊啊啊。