改进表单
同上一章一样,我们先从最为简单、有效的例子开始。现在我们再来找出这个简单的例子中的不足,然后改进他们。
首先,search()
视图对于空字符串的处理相当薄弱——仅显示一条"Please submit a search term."
的提示信息。若用户要重新填写表单必须自行点击“后退”按钮,这种做法既糟糕又不专业。如果在现实的案例中,我们这样子编写,那么Django的优势将荡然无存。
在检测到空字符串时更好的解决方法是重新显示表单,并在表单上面给出错误提示以便用户立刻重新填写。最简单的实现方法既是添加else分句重新显示表单,代码如下:
from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book
def search_form(request):
return render_to_response('search_form.html')
def search(request):
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
else:
return render_to_response('search_form.html', {'error': True})
(注意,将search_form()
视图也包含进来以便查看)
这段代码里,我们改进了search()
视图:在字符串为空时重新显示search_form.html
。 并且给这个模板传递了一个变量error
,记录着错误提示信息。现在我们编辑一下search_form.html
,检测变量error
:
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
**<p style="color: red;">Please submit a search term.</p>**
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
我们修改了search_form()
视图所使用的模板,因为search_form()
视图没有传递error
变量,所以在条用search_form
视图时不会显示错误信息。
通过上面的一些修改,现在程序变的好多了,但是现在出现一个问题:是否有必要专门编写search_form()
来显示表单?按实际情况来说,当一个请求发送至/search/
(未包含GET的数据)后将会显示一个空的表单(带有错误信息)。所以,只要我们改变search()
视图:当用户访问/search/
并未提交任何数据时就隐藏错误信息,这样就移去search_form()
视图以及对应的URLpattern
。
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
return render_to_response('search_form.html',
{'error': error})
在改进后的视图中,若用户访问/search/
并且没有带有GET
数据,那么他将看到一个没有错误信息的表单;如果用户提交了一个空表单,那么它将看到错误提示信息,还有表单;最后,若用户提交了一个非空的值,那么他将看到搜索结果。
最后,我们再稍微改进一下这个表单,去掉冗余的部分。既然已经将两个视图与URLs
合并起来,/search/
视图管理着表单的显示以及结果的显示,那么在search_form.html
里表单的action
值就没有必要硬编码的指定URL。原先的代码是这样:
<form action="/search/" method="get">
现在改成这样:
<form action="" method="get">
action=" "意味着表单将提交给与当前页面相同的URL
。这样修改之后,如果search()
视图不指向其它页面的话,你将不必再修改action
。
{$ activeFileHint $}