将表格与视图绑定

我们的联系表单对我们来说并不是什么好事,除非我们有一些方式向用户展示。 要做到这一点,我们需要先更新我们的mysite \ views.py:

# mysite_project\mysite\mysite\views.py

from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
import datetime
from mysite.forms import ContactForm    
from django.core.mail import send_mail, get_connection

# ...

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            con = get_connection('django.core.mail.backends.console.EmailBackend')
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', '[email protected]'),
                ['[email protected]'],
                connection=con
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()

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

我们已经将联系功能添加到我们的视图来处理表单提交。 在这个新功能中,我们:

  • 检查请求是否用POST方法提交,否则我们只显示空白表单。

  • 然后我们通过调用表单的is_valid()方法来检查表单是否包含有效的数据。

    • 如果表单包含有效的数据,则发送电子邮件并将用户重定向到新视图(/ contact / thanks /)。

    • 如果表单不包含有效数据,则if块跳转到最终的render(),并将表单呈现回浏览器。

请注意,我们不在视图中进行任何错误处理 - 这全部由表单类处理。 如果表单没有验证,Django会自动创建一个错误列表并将它们追加到响应中。

联系表单没有太多用处,没有办法将联系表单信息发送给网站所有者。 这样做的一个非常普遍的方式是发送电子邮件。 Django能够发送内置到核心的电子邮件。 电子邮件功能可以在django.core.mail模块中找到,我已经在我们修改过的views.py的顶部导入了这个模块。

我们使用send_mail()函数将电子邮件发送到一个虚拟的电子邮件地址。 您可以在Django文档中的send_mail()以及其他电子邮件函数和类中找到更多信息。

在开发中发送电子邮件

您会注意到我正在使用django.core.mail.get_connection()来检索到特定电子邮件后端名为“django.core.mail.backends.console.EmailBackend”的邮件连接。 这个后端在开发中特别有用,因为它不需要你在开发一个Django应用程序的时候设置一个电子邮件服务器。 console.EmailBackend将电子邮件输出发送到控制台。 提交表格后,您可以在终端窗口中查看。
还有其他的电子邮件后台用于测试 - firebased,locmem和dummy,它们将您的电子邮件发送到本地系统上的文件,将其保存在内存中的属性中,并分别发送到虚拟后端。
您可以在电子邮件后台下的Django文档中找到更多信息。

为了能够显示我们的联系表格,我们必须创建我们的联系表格(保存为mysite \ templates):

# mysite_project\mysite\templates\contact_form.html



    Contact us


    

Contact us

{% if form.errors %}

Please correct the error{{ form.errors|pluralize }} below.

{% endif %}
{{ form.as_table }}
{% csrf_token %}

由于我们正在创建一个POST表单(这可能会影响修改数据),所以我们需要担心跨站点请求伪造。 值得庆幸的是,您不必太担心,因为Django带有一个非常容易使用的系统来保护它。

简而言之,所有以内部URL为目标的POST表单都应使用{%csrf_token%}模板标记。 关于{%csrf_token%}的更多细节可以在第19章找到。

敏锐的读者也会注意到

标签中的novalidate属性。 在某些最新版本的浏览器(特别是Chrome)中使用HTML5时,浏览器会自动验证表单字段。 因为我们希望Django处理表单验证,所以novalidate属性告诉浏览器不要验证表单。

最后,我们需要更改我们的urls.py以在/ contact /中显示我们的联系表单:

 # ...
from mysite.views import hello, current_datetime, hours_ahead, contact

 urlpatterns = [
     # ...
     url(r'^contact/$', contact),
     url(r'^', include('books.urls')),
]

尝试在本地运行。 加载表单,填写任何一个字段(图6-5),提交一个无效的电子邮件地址(图6-6),最后提交有效的数据。
将表格与视图绑定_第1张图片
图6-5。 Django表单类提供了字段的自动验证。.png
将表格与视图绑定_第2张图片
图6-6。 Django也检查有效的电子邮件地址。.png

请注意,当您提交完整的表单时,您将收到“页面未找到(404)”错误。 这是因为我还没有创建重定向到/ contact / thanks /的视图或URLconf。 我会把这个留给你作为一个学习练习。

更改字段的呈现方式

当您在本地呈现此表单时,您可能会首先注意到消息字段显示为,并且应该是