django表单在刷新时重新提交

时间:2011-04-28 18:55:48

标签: django forms

我第一次提交表单然后刷新表单后重新提交,我不希望这样。

这是模板中的表单:

<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))

5 个答案:

答案 0 :(得分:35)

我的猜测是你认为这是一个问题。

成功提交和处理网络表单后,即使您只是重定向到同一视图,也需要使用返回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 :(得分:1)

最有可能的是:在提交表单后刷新时,您再次显示相同的表单页面(不做任何操作)。您需要在提交表单后重定向到记录页面或新页面。

这样,表单变为空数据,刷新时不会重新提交。

答案 2 :(得分:1)

简单尝试

返回重定向('url', parameter_if_needed)

代替

返回渲染(请求,'name.hmtl',上下文)

就我而言,它完美无缺

答案 3 :(得分:0)

使用 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命中时,会一次又一次地调用同一个视图,因此会在数据库中保存多个条目。为防止这种情况发生,我们需要将响应重定向到新的网址/视图,以便下次页面刷新时会触及新的网址/视图。

答案 4 :(得分:0)

此解决方案对我有用。提交表单后,我们必须以任何形式的弹出窗口或文本形式在模板中显示一条消息,因此,尽管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 %}