Усовершенствование примера обработки формы
Как обычно, мы начали с простейшего работающего примера. А теперь рассмотрим некоторые проблемы и покажем, как их можно решить.
Во-первых, обработка пустого запроса в представлении searchQ явно недостаточна – мы просто выводим сообщение «Введите поисковый запрос», заставляя пользователя нажать кнопку «Назад» в броузере. Это крайне непрофессионально, и, если вы сделаете нечто подобное в действующем приложении, вас отлучат от Django.
Гораздо лучше будет вывести форму повторно, поместив над ней сообщение об ошибке, – тогда пользователь сможет сразу же повторить запрос. Для этого проще всего еще раз выполнить отображение шаблона:
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_responseCsearch_form.html’, {‘error’: True})
(Мы также включили в пример представление search_form(), чтобы вы могли видеть оба представления одновременно.)
Здесь мы улучшили метод searchQ, и теперь он повторно отображает шаблон search_form.html, если запрос пуст. А поскольку на этот раз нам нужно вывести сообщение об ошибке, то мы передаем в шаблон пере-
Естественно, в русскоязычной версии окончание V выводить не нужно, так что pluralize, пожалуй, излишне. – Прим. перев.
Интересное решение проблемы русификации фильтра pluralize можно найти по адресу: http://vas3k.ru/work/django_ru_pluralize. – Прим. науч. ред.
менную. Сам же шаблон search_form.html следует изменить так, чтобы он проверял переменную error.
<html> <head>
<title>noMCK</title> </head> <body>
{% if error %}
<p style="color: red;">Введите поисковый запрос.</p> {% endif %}
<form action="/search/" method="get"> <input type=,,text" name="q"> <input type="submit" уа1ие="Найти"> </form> </body> </html>
Мы можем использовать этот шаблон и в первоначальном варианте представления search_form(), потому что search_form() не передает error в шаблон, следовательно, сообщение об ошибке выводиться не будет.
После этого изменения приложение стало лучше, но возникает вопрос: а так ли необходимо отдельное представление search_form()? Сейчас запрос к URL /search/ (без GET-параметров) приводит к выводу пустой формы (но с сообщением об ошибке). Мы можем удалить представление search_form() вместе с соответствующим шаблоном URL при условии, что изменим search() так, чтобы при обращении к URL /search/ без параметров сообщение об ошибке не выводилось:
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})
Теперь, обратившись к URL /search/ без параметров, пользователь увидит форму поиска без сообщения об ошибке. Если же он отправит форму с пустым значением ‘q’, то увидит ту же форму, но уже с сообщением об ошибке. И наконец, при наличии в отправленной форме непустого значения * q’ будут выведены результаты поиска.
Мы можем внести в это приложение еще одно, последнее, улучшение – устранить некоторую избыточность. После того как два представления
(и два образца URL) слились в одно, а представление /search/ стало обрабатывать не только вывод формы поиска, но и вывод результатов, отпала необходимость «зашивать» URL в HTML-тег <form> в файле search_ form.html. Вместо
<form actions’/search/" method="get">
можно написать:
<form action="" method="get">
Атрибут action^"" означает «Отправить форму на URL текущей страницы». При таком изменении не потребуется изменять action, если с представлением search() будет ассоциирован другой URL.
Источник: Головатый А., Каплан-Мосс Дж. Django. Подробное руководство, 2-е издание. – Пер. с англ. – СПб.: Символ- Плюс, 2010. – 560 е., ил.
