Found misprint?

Select it with the mouse and hit Enter

Ctrl-Enter
Обработано:
86 1 199 25
на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!

ЯМ:41001223475816

Редактор ресурсов Gettext для Android
The full repository of DjangoBook translation you can get on GitHub.
We appreciate your patches!
Мы рады получить ваши вопросы, комментарии или предложения!
(Open in new tab)
Количество пользователей: 1135
Русская группа
на Google

Документация Django на русском

Документация на русском языке для Django стала реальностью. Благодаря новым возможностям движка Sphinx мы можем оперативно дополнять перевод, по мере обновления оригинальной документации.

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

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

Обычно, разработка форм подразумевает два шага: пользовательский интерфейс в 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 (прим. переводчика).

Quicker
Quicker 2 недели, 3 дня прошло
Ответить | Ссылка

Создал search_form в файле views.py в папке books. Добавил в папку с шаблонами search_form.html. Прописал в urls.py (r'^search-form/$', views.search_form),
При попытке зайти на 127.0.0.1:8000/search-form/ получаю ошибку
AttributeError at /search-form
'module' object has no attribute 'search_form'
Как я понимаю, в urls.py не получается импортировать search_form из views.py. Несколько раз перепроверял правильность имен, переменная PATH в порядке. Кто-нибудь может подсказать, в чем еще может быть проблема?

alerion
alerion 1 год, 8 месяцев прошло
Ответить | Ссылка

ответить misha.panyushkin
значит, запятая в конце одно элементного кортежа не нужна?
return render_to_response('search_form.html')

Нужна, но с чего вы взяли что там должен быть кортеж: http://docs.djangoproject.com/en/1.3/topics/http/shortcuts/#render-to-response

misha.panyushkin
misha.panyushkin 1 год, 8 месяцев прошло
Ответить | Ссылка

ответить alerion
Да нет, вроде все правильно

значит, запятая в конце одно элементного кортежа не нужна?
return render_to_response('search_form.html')

alerion
alerion 1 год, 8 месяцев прошло
Ответить | Ссылка

ответить misha.panyushkin
здравствуйте,
в самом начале, Вы забыли о том, что render_to_response принимает кортеж! пропущена запятая в конце одно элементного кортежа!

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

Да нет, вроде все правильно

misha.panyushkin
misha.panyushkin 1 год, 8 месяцев прошло
Ответить | Ссылка

здравствуйте,
в самом начале, Вы забыли о том, что render_to_response принимает кортеж! пропущена запятая в конце одно элементного кортежа!

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

communyaka
communyaka 1 год, 9 месяцев прошло
Ответить | Ссылка

ответить alerion
Или просто request.GET.get('q')

if request.GET.get('q') <> None:

Вот так отрабатывает правильно в обоих случаях.
В других не отрабатывается пустая строка из-за "?q".

alerion
alerion 1 год, 9 месяцев прошло
Ответить | Ссылка

ответить kibarabara
При "if request.GET['q']:" и отстуствии ?q будет исключение KeyError.
Именно поэтому ниже идет написано:
if 'q' in request.GET and request.GET['q']:

Или просто request.GET.get('q')

kibarabara
kibarabara 1 год, 9 месяцев прошло
Ответить | Ссылка

ответить nazavrik
В коде:
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'

есть две баги.

1. При пустом запросе мы будем получать true (/search/?q=). Нужно исправить:

if request.GET['q']:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'

2. Запрос юникодной строки будет выводить не символы, а коды символов. Нужно изменить формат вывода:

message = 'You searched for: %s(!)' % request.GET['q']

При "if request.GET['q']:" и отстуствии ?q будет исключение KeyError.
Именно поэтому ниже идет написано:
if 'q' in request.GET and request.GET['q']:

nazavrik
nazavrik 1 год, 10 месяцев прошло
Ответить | Ссылка

В коде:
if 'q' in request.GET:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'

есть две баги.

1. При пустом запросе мы будем получать true (/search/?q=). Нужно исправить:

if request.GET['q']:
message = 'You searched for: %r' % request.GET['q']
else:
message = 'You submitted an empty form.'

2. Запрос юникодной строки будет выводить не символы, а коды символов. Нужно изменить формат вывода:

message = 'You searched for: %s(!)' % request.GET['q']

rad
rad 1 год, 10 месяцев прошло
Ответить | Ссылка

Для вопросов создан форум.

По делу: у вас проблемы с кодировками.

Exile
Exile 1 год, 10 месяцев прошло
Ответить | Ссылка

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)

Если захочу в переменную message вводить на русском к примеру
message = 'Вы искали : %r' % request.GET['q']
то мне выводится этот текст в виде
�� ������

Как это исправить?
так же когда ищу на русском, то в выводятся не буквы а их код, к примеру ввел в поиск "джанго" , на странице пишется вместо "Вы искали: джанго"
�� ������ u'\u0434\u0436\u0430\u043d\u0433\u043e'

rad
rad 1 год, 10 месяцев прошло
Ответить | Ссылка

Надо использовать {{ csrf_token }} в формах:
http://docs.djangoproject.com/en/1.2/topics/forms/#displaying-a-form-using-a-template

solyony
solyony 1 год, 10 месяцев прошло
Ответить | Ссылка

Forbidden (403)
CSRF verification failed. Request aborted.

Help
Reason given for failure:
CSRF token missing or incorrect.

Я поменял GET на POST а оно мне вот ошибку, что это может быть??

rad
rad 2 года прошло
Ответить | Ссылка

Задайте свой вопрос более развёрнуто на форуме.

bordik
bordik 2 года прошло
Ответить | Ссылка

Подскажите, как сделать чтоб строка ввода (input) переводилась в unicode ?