首页 > 代码库 > contact表单错误解决记录

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))

报错如下

 

小结

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