Главная | Архив новостей | Общение | Площадка | Примеры OpenID
Хостинг Django от «Джино»
Оглавление

Пример обработки простой формы

Продолжая наш пример с книгами, авторами и издателями, давайте создадим простое представление, которое позволит пользователям производить поиск по нашей базе книг по их названию.

Обычно, разработка форм подразумевает два шага: пользовательский интерфейс в HTML и код сопровождающего представления, которое обрабатывает переданные данные. Первый шаг несложен. Давайте создадим представление, которое отображает поисковую форму:

from django.shortcuts import render_to_response

def search_form(request):
    return render_to_response('search_form.html')

Как мы уже говорили в главе «Представления и привязки URL», представление может располагаться где угодно, пока оно находится через PYTHONPATH. Для порядка разместим его в books/views.py.

Соответствующий шаблон, search_form.html, может выглядеть так:

<html>
<head>
    <title>Search</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>

Схема URL в urls.py может выглядеть так:

from mysite.books import views

urlpatterns = patterns('',
    # ...
    (r'^search-form/$', views.search_form),
    # ...
)

(Следует отметить, что мы импортируем модуль viewsнапрямую, а не указывает from mysite.views import search_form, поскольку первый метод более краток. Мы рассмотрим этот механизм импортирования более подробно в главе «Усовершенствованные представления и схемы URL».)

Если вы запустите runserver и посетите http://127.0.0.1:8000/search-form/, вы увидете поисковый интерфейс. Очень простой.

Попробуйте отправить форму, несмотря на то, что вы получите ошибку 404. Форма указывает на URL /search/, обработчик которого ещё не был реализован. Давайте это исправим с помощью второй функции представления:

# urls.py

urlpatterns = patterns('',
    # ...
    (r'^search-form/$', views.search_form),
    (r'^search/$', views.search),
    # ...
)

# views.py

def search(request):
    if 'q' in request.GET:
        message = 'You searched for: %r' % request.GET['q']
    else:
        message = 'You submitted an empty form.'
    return HttpResponse(message)

На данный момент, этот код просто отображает пользовательский ввод, таким образом мы можем удостовериться, что данные были переданы корректно и вы можете увидеть как работает поисковая система. Если кратко:

  1. Тег <form> определяет переменную q. При отправке формы, значение этой переменной посылается через GET (method="get") на URL /search/.

  2. Представление обрабатывающее URL /search/ (search()) получает доступ к значению переменной q через request.GET.

Обратите внимание, мы явно проверяем существование переменной q в request.GET. Как мы говорили ранее, вы должны проявлять должное недоверие к данным, переданным пользователями. Если бы мы не сделали такую проверку, то любая передача пустой формы приводила бы к вызову сключения KeyError в представлении:

# BAD!
def bad_search(request):
    # The following line will raise KeyError if 'q' hasn't
    # been submitted!
    message = 'You searched for: %r' % request.GET['q']
    return HttpResponse(message)

Параметры строки запроса

Так как GET данные передаются в строке запроса (т.е., /search/?q=django), вы можете использовать request.GET для доступа к переменным, переданным в этой строке. В главе «Представления и привязки URL» при ознакомлении со схемой URL, мы сравнивали подход Django к формированию URL с традиционными PHP/Java URL, например, /time/plus?hours=3 и обещали вернуться к этому в этой главе. Теперь вы знаете как получать доступ к параметрам строки запроса в ваших представлениях — просто используйте request.GET.

POST данные обрабатываются аналогично GET — только используйте request.POST вместо request.GET. Какая разница существует между GET и POST? Используйте GET в случаях, когда форма используется для «получения» данных[9]. Используйте POST при обработке форм, которая имеет сторонний эффект — изменение данных или при отправке электронных сообщений, в общем для всего, что лежит вне задачи простого отображения данных. В нашем примере мы используем GET, так как запрос не изменяет данные на сервере. (Обратитесь к http://www.w3.org/2001/tag/doc/whenToUseGet.html, если вы желаете узнать больше о GET и POST).

После того как мы проверили переданные данные, давайте используем их для поиска по базе данных (и снова, в views.py):

from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book

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 HttpResponse('Please submit a search term.')

Остановимся и опишем, что мы сделали:

  • Помимо проверки существования q в request.GET, мы удостоверились, что request.GET['q'] не содержит пустую строку, перед её передачей в базу данных.

  • Мы используем Book.objects.filter(title__icontains=q) для поиска по нашей таблице книг, разыскивая книги у которых заголовок содержит переданную строку. Суффикс icontains является модификатором (это было рассмотрено в главе «Модели» и в Приложении B FIXME) и данный оператор может быть приблизительно переведён в «Получить все книги, названия которых содержат q, не принимая во внимание регистр букв.»

    Это очень простой способ реализации поиска книг. Мы не рекомендуем использовать простой icontains запрос на больших реальных базах данных, так как он может быть очень медленным. (В реальном мире, вам потребуется собственная поисковая система. Поищите в Интернет полнотекстовую поисковую систему с открытым кодом, чтобы получить информацию о их возможностях.)

  • Мы передаём books, список объектов Book, в шаблон. Шаблонный код в файле search_results.html может выглядеть так:

    <p>You searched for: <strong>{{ query }}</strong></p>
    
    {% if books %}
        <p>Found {{ books|length }} book{{ books|pluralize }}.</p>
        <ul>
            {% for book in books %}
            <li>{{ book.title }}</li>
            {% endfor %}
        </ul>
    {% else %}
        <p>No books matched your search criteria.</p>
    {% endif %}
    



[9] Всегда используйте в форм только POST (прим. переводчика).


Увидели ошибку?
Выделите её мышкой и нажмите
Ctrl-Enter
Обработано:
1049 49 130 71

Версия книги
1.0 2.0
Версия 2.0 в процессе перевода!

Мой луч
Многообразие света

Полезное
Актуальные вакансии, Python работа для python-разработчиков.


Скачать в формате
CHM от 2 сентября

Заказать PDF файл можно через почту, чат, джаббер. Всего 2WMZ. Содержимое точно соответствует содержимому сайта.
Чем чаще заказываете — тем больше перевожу.

Русская группа

на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!
R130494980980
Z425285133788
E112528079659
U327380922061

Книга помогла реализовать:
Проект «Мой луч»
АРМ УФМС.


Мой вебсайт стоит666 337,31 руб

© 2008-2009 Ruslan Popov @ gmail.com Powered by Django 1.1 beta 1 SVN-11114
Главная | Архив новостей | Общение | Площадка | Примеры OpenID