форма django повторно отправлена при обновлении

#django #forms

#django #формы

Вопрос:

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

Вот моя форма в шаблоне :

 <form action = "" method = "POST"> {% csrf_token %}
    {{ form.as_p }}
    <input type = "submit" value = "Shout!"/>
</form>
  

Как я могу это исправить?

Вот мои взгляды:

 def index(request):
    shouts = Shout.objects.all()

    if request.method == "POST":
        form = GuestBookForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            shout = Shout(author = cd['author'], message = cd['message'])
            shout.save()
            form = GuestBookForm()
    else:
        form = GuestBookForm()

    return render_to_response('guestbook/index.html', {'shouts' : shouts,
                                             'form' : form },
                              context_instance = RequestContext(request))
  

Ответ №1:

Я предполагаю, что, на ваш взгляд, это проблема.

После успешной отправки и обработки веб-формы вам необходимо использовать возврат HttpResponseRedirect, даже если вы перенаправляете только на то же представление. В противном случае некоторые браузеры (я почти уверен, что FireFox делает это) в конечном итоге отправят форму дважды.

Вот пример того, как с этим справиться…

 def some_view(request):
  if request.method == "POST":
    form = some_form(request.POST)
    if form.is_valid():
      # do processing
      # save model, etc.
      return HttpResponseRedirect("/some/url/")
  return render_to_response("normal/template.html", {"form":form}, context_instance=RequestContext(request))
  

Учитывая ваш недавно добавленный вид выше…

 def index(request):
    shouts = Shout.objects.all()

    if request.method == "POST":
        form = GuestBookForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            shout = Shout(author = cd['author'], message = cd['message'])
            shout.save()

            # Redirect to THIS view, assuming it lives in 'some app'
            return HttpResponseRedirect(reverse("some_app.views.index"))
    else:
        form = GuestBookForm()

    return render_to_response('guestbook/index.html', {'shouts' : shouts,
                                         'form' : form },
                          context_instance = RequestContext(request))
  

Это будет использовать reverse для перенаправления на это же представление (если это то, что вы пытаетесь сделать)

Комментарии:

1. Я думаю, что все в порядке. У меня была догадка, и я ответил на это до того, как OP ввел представления.

2. Ах, я вижу, он добавил просмотры, пока я публиковал. Я могу изменить это, чтобы соответствовать.

3. Нет необходимости изменять, у меня уже все работает правильно, спасибо!

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

5. Как реализовать метод: some_form , я не вижу никакого встроенного API. (django 1.9)

Ответ №2:

Попробуйте:

return redirect ('url', parameter_if_needed)

вместо

return render (request, 'name.hmtl', context)

В моем случае это работает отлично.

Комментарии:

1. имя ‘redirect’ не определено

2. просто импортируйте перенаправление

Ответ №3:

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

Таким образом, форма становится пустой из своих данных и не будет повторно отправлена при обновлении.

Ответ №4:

Я нашел способ, и я думаю, что это сработает для любого веб-сайта. что вам нужно сделать, это добавить Htmx cdn или вы можете вызвать библиотеку javascript из htmx.org похоже на загрузочный CDN.

добавьте это

  before body tag

<script src="https://unpkg.com/htmx.org@1.6.0"></script>
  

добавьте это или перейдите на их веб-сайт htmx.org

затем, что вам нужно сделать, это перейти к тегу вашей формы и добавить это….

hx-post=" then add the path in here, where you want to redirect" что-то вроде этого..

связаться с html

 <form hx-post="/contact" hx-target="body" method="post">
 </form>
  

вы должны добавить цель в зависимости от вашего типа формы. Приведенный выше пример представляет собой контактную форму, я хочу, чтобы эта контактная форма оставалась на той же странице и предназначалась для ее тела следующим образом hx-target =»body»

views.py

 return render(request, "blog/contact.html")
  

Ответ №5:

Используйте HttpResponseRedirect

создайте новое представление (допустим, thank_you ) для успешного отображения сообщения после отправки формы и верните шаблон.

После успешной отправки формы верните HttpResponseRedirect («/ thank-you /») в новое представление благодарности

 from django.http import HttpResponseRedirect

def thank_you(request, template_name='thank-you.html'):
    return render_to_response(template_name,locals(),context_instance=RequestContext(request))
  

и в urls.py

 url(r'^thank-you/$','thank_you', name="thank_you")
  

Многократная отправка формы происходит потому, что при обновлении страницы попадает тот же URL, который снова и снова вызывает то же представление и, следовательно, сохраняет несколько записей в базе данных. Чтобы предотвратить это, мы должны перенаправить ответ на новый URL / просмотр, чтобы при следующем обновлении страницы он попадал на этот новый URL / просмотр.

Ответ №6:

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

 from django.contrib import messages

def index_function(request):
     if request.method == "POST":
     form = some_form(request.POST)
     if form.is_valid():
        # do processing
        # save model, etc.
        messages.success(request, 'Form successfully submitted') # Any message you wish
     return HttpResponseRedirect("/url")
  

Затем внутри вашего шаблона вы можете отобразить это сообщение. Поскольку это глобальный параметр, вы можете отобразить его в любом HTML-шаблоне, подобном следующему.

 {% if messages %}
<div class="alert alert-success alert-dismissible">
  {% for message in messages %}
    <p>{{ message }}</p>
  {% endfor %}
</div>
{% endif %}