contact表单错误解决记录

在上篇表单验证中,过程中可谓坎坷,记录一下错误问题及解决方案。

我们用到的模板contact_form.html如下,其他urls.py自行去修改。

<html>
<head>
    <title>Contact us</title>
</head>
<body>
    <h1>Contact us</h1>

    {% if errors %}
    <ul>
        {% for error in errors %}
        <li>{{ error }}</li>
        {% endfor %}
    </ul>
    {% endif %}

    <form action="/contact/" method="post">
        <p>Subject: <input type="text" name="subject"></p>
        <p>Your e-mail (optional): <input type="text" name="email"></p>
        <p>Message: <textarea name="message" rows="10" cols="50"></textarea></p>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

视图函数

 1 from django.core.mail import send_mail
 2 from django.http import HttpResponseRedirect
 3 
 4 def contact(request):
 5     errors = []
 6     if request.method == 'POST':
 7         if not request.POST.get('subject', ''):
 8             errors.append('Enter a subject.')
 9         if not request.POST.get('message', ''):
10             errors.append('Enter a message.')
11         if request.POST.get('email') and '@' not in request.POST['email']:
12             errors.append('Enter a valid e-mail address.')
13         if not errors:
14             try:
15                 send_mail(
16                     request.POST['subject'],
17                     request.POST['message'],
18                     request.POST.get('email', 'noreply@example.com'),
19                     ['siteowner@example.com'],
20                     )
21             except:
22                 return HttpResponse("exception.")
23 
24             return HttpResponseRedirect('/contact/thanks/')
25     return render_to_response('contact_form.html',
26         {'errors': errors})

由于这示例是个发送邮件,而本地不一定配置了相关环境,我们使用简单地Console backend进行输出邮件内容。

只需要在settings.py中增加如下一句即可:

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

我们的视图方法很简单,发送邮件成功(dos窗口会输出邮件相关信息),并转向到thanks视图;失败则会停留在本页并提示错误。

方法看似没问题,可是执行看一下结果(下图是输入正确或错误一样的结果截图,也就是response时候的错误)

针对该问题进行查找解决方案,并一点点修改。

首先引入RequestContext

from django.template import Context,RequestContext

修改模板中加入

1 <form action="/contact/" method="post">
2         {% csrf_token %}
3         <p>Subject: <input type="text" name="subject"></p>
4         <p>Your e-mail (optional): <input type="text" name="email"></p>
5         <p>Message: <textarea name="message" rows="10" cols="50"></textarea></p>
6         <input type="submit" value="Submit">
7     </form>

settings.py中添加的那个CsrfViewMiddleware,在原来的配置中就是包含的,不用管。再进行查看结果,还是一样的!这里就不贴图了。

想想我们唯一的改动就是增加了一个模块类RequestContext,但是他有什么用呢?我们并没有改动代码,是不是它对代码会有什么影响?

官网上有这样一段示例

return render_to_response('my_template.html',
                          my_data_dictionary,
                          context_instance=RequestContext(request))

和我们的视图函数中是不一样的!

参照这个示例,我们开始修改视图:

 1 def contact(request):
 2     errors = []
 3     if request.method == 'POST':
 4         if not request.POST.get('subject', ''):
 5             errors.append('Enter a subject.')
 6         if not request.POST.get('message', ''):
 7             errors.append('Enter a message.')
 8         if request.POST.get('email') and '@' not in request.POST['email']:
 9             errors.append('Enter a valid e-mail address.')
10         if not errors:
11             try:
12                 send_mail(
13                     request.POST['subject'],
14                     request.POST['message'],
15                     request.POST.get('email', 'noreply@example.com'),
16                     ['siteowner@example.com'],
17                     )
18             except:
19                 return HttpResponse("exception.")
20 
21             return HttpResponseRedirect('/contact/thanks/')
22     return render_to_response('contact_form.html',
23         {'errors': errors},context_instance=RequestContext(request))

 

我们增加了这一句,然后看效果吧

okay,我们成功了!

当我们输入正确的邮箱时,正确跳转到thanks视图,效果如下:

 

顺便一提,在我们的dos窗口看到了邮件信息,说明settings.py中的那一句还是好用的:

 

最终的视图函数如下

 1 from django.template import Context,RequestContext
 2 from django.core.mail import send_mail
 3 from django.http import HttpResponseRedirect
 4 
 5 def contact(request):
 6     errors = []
 7     if request.method == 'POST':
 8         if not request.POST.get('subject', ''):
 9             errors.append('Enter a subject.')
10         if not request.POST.get('message', ''):
11             errors.append('Enter a message.')
12         if request.POST.get('email') and '@' not in request.POST['email']:
13             errors.append('Enter a valid e-mail address.')
14         if not errors:
15             try:
16                 send_mail(
17                     request.POST['subject'],
18                     request.POST['message'],
19                     request.POST.get('email', 'noreply@example.com'),
20                     ['siteowner@example.com'],
21                     )
22             except:
23                 return HttpResponse("exception.")
24 
25             return HttpResponseRedirect('/contact/thanks/')
26     return render_to_response('contact_form.html',
27         {'errors': errors},context_instance=RequestContext(request))
28 
29 def thanks(request):
30     return HttpResponse("thanks for your suggestion!")

模板如下

 1 <html>
 2 <head>
 3     <title>Contact us</title>
 4 </head>
 5 <body>
 6     <h1>Contact us</h1>
 7 
 8     {% if errors %}
 9     <ul>
10         {% for error in errors %}
11         <li>{{ error }}</li>
12         {% endfor %}
13     </ul>
14     {% endif %}
15 
16     <form action="/contact/" method="post">
17         {% csrf_token %}
18         <p>Subject: <input type="text" name="subject"></p>
19         <p>Your e-mail (optional): <input type="text" name="email"></p>
20         <p>Message: <textarea name="message" rows="10" cols="50"></textarea></p>
21         <input type="submit" value="Submit">
22     </form>
23 </body>
24 </html>

 

注意:

return HttpResponseRedirect('/contact/thanks/')

这只是一个普通的HttpResponse,不可修改如下

return HttpResponseRedirect('/contact/thanks/',context_instance=RequestContext(request))

报错如下

 

小结

有问题是好事,解决问题的过程,能学到更多东西,继续加油!

posted @ 2014-07-29 11:21  棉花年度  阅读(417)  评论(0编辑  收藏  举报