Где обрабатываются данные формы? (Джанго)

Я прочитал много статей и документации по созданию и обработке форм в Django, но я все еще не уверен в некоторых аспектах реализации. В частности, я не могу понять, где я должен обрабатывать данные, отправленные формой. Это в представлении, которое использует шаблон формы, или в другом представлении?

Например, предположим шаблон индекса с одной формой:

*index.html*
{% load url from future %}
<form action="{% url 'Directories:_results'%}" method="post">
Name: <input type="text" name="txtField" />
<input type="submit" name="submit" />
</form>

Итак, на мой взгляд, у меня есть две версии:

Версия #1 (1 вид): тот же вид отображает и обрабатывает форму

def index(request):
    if request.method == 'POST': # If the form has been submitted...
        form = dbForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            field = form.cleaned_data['txtField']
            #doSomething
    else:
        form = dbForm() #unbound form
     return render(request, 'Directories/index.html', {'form': form})

#2 версия (2 вида): один вид для отображения формы и один вид для обработки данных формы

#the view that creates the form (unbound)
def index(request):
    form = dbForm()
    return render(request, 'Directories/index.html', {'form':form})

#the view that handles the data sent during form submission in the index template.
def results(request):
    if request.method == 'POST':
        form = dbForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            field = form.cleaned_data['txtField']
            #doSomething
     else:
         form = dbForm() #unbound form
     return render(request, 'Directories/index.html', {'form': form})

и вот мой urls.py:

from django.conf.urls import patterns, url
from Directories import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='_index'),
    url(r'^results$', views.results, name='_results'),)

Как вы можете видеть, обработка данных выполняется по-разному в каждой версии, и в результате я хочу знать, если какой-либо из них является неправильным, и если оба являются правильными, то какой из них считается наилучшей практикой.

4 ответа

Решение

Обычно форма публикуется в том же виде, в котором она отображается.

Вы можете упростить логику представления следующим образом:

def index(request):
    form = dbForm(data=request.POST or None)
    if form.is_valid(): # All validation rules pass
        field = form.cleaned_data['txtField']
        #doSomething
        return redirect(success_url)
    return render(request, 'Directories/index.html', {'form': form})

Обратите внимание, что обычно хорошо, если вы перенаправляете после успешной публикации формы, даже если вы перенаправляете обратно в то же представление. Это препятствует тому, чтобы пользователю предлагали "повторно отправить данные формы", если они обновляют страницу.

Вы должны взглянуть на документы для рендеринга формы в шаблоне:
https://docs.djangoproject.com/en/dev/topics/forms/

Например, если вы не визуализируете ошибки поля, пользователь никогда не узнает, в чем проблема.

Пример формы, которая будет публиковать в другом представлении, если, скажем, ваш базовый шаблон имеет форму "поиска", которая появляется на каждой странице. Когда вы публикуете эту форму, вы не хотите возвращаться к текущему представлению, вы хотите перейти к представлению "результаты поиска".

Как правило, один вид соответствует одному URL. Кроме того, тот же URL должен показать форму и принять отправленную форму. С этой логикой ваш первый подход лучше. Один вид показывает и принимает форму.

Однако есть случаи, когда представление для отображения формы отличается от того, которое принимает ее. Например, страница, которая имеет несколько форм. Каждая форма может быть представлена ​​в другом представлении. Но для обработки этого URL и отображения таких форм может быть реализовано другое представление.

В этом нет ничего плохого, это зависит от того, что вы хотите сделать. По умолчанию формы отправляют данные в один и тот же запрос, но вы можете отправить данные в другое представление, если это более удобно

В большинстве случаев обычно проще использовать один и тот же вид. Использование двух представлений хорошо, если вы используете внешний инструмент \ приложение \ что угодно или если вы хотите усилить безопасность (второе представление принимает запросы только с данными публикации, например и т. Д.), Но потребует дополнительных шагов (обработка ошибок, успешный редирект)

Первое, что нужно понять, это то, что представление, которое обрабатывает форму, как правило, также является тем, которое отображает форму в первую очередь - потому что оно должно снова показывать форму в случае ошибок.

В своем шаблоне вы создаете форму HTML полностью вручную. Это необычно, потому что в случае ошибок (обычно это обязательное поле, которое не было заполнено), вы хотите снова отобразить форму со всеми уже введенными значениями и с хорошим сообщением об ошибке. Визуализация формы Джанго ({{ form.as_p }} и тому подобное) сделайте это за вас, вы не получите этого, если будете писать HTML-код от руки так. Фактически, ваше представление пропускает предложение else: в is_valid(), приводя его к

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

Таким образом, ваш 1-й типичен, за исключением того, что вам также нужно закончить с возвратом ResponseRedirect в случае is_valid(), и он должен визуализировать больше формы в вашем шаблоне. Нет необходимости во втором просмотре.

Другие вопросы по тегам