【问题标题】:django form resubmitted upon refresh刷新时重新提交的django表单
【发布时间】:2011-08-14 23:31:06
【问题描述】:

在我第一次提交表单并刷新表单后,它会重新提交,我不希望这样。

这是我在模板中的表格:

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

【问题讨论】:

    标签: django forms


    【解决方案1】:

    我的猜测是,在您看来这是一个问题。

    在成功提交和处理 Web 表单后,您需要使用返回 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 重定向到同一个视图(如果您正在尝试这样做)

    【讨论】:

    • 我认为是正确的。在 OP 提出观点之前,我有预感并回答了这个问题。
    • 啊,我看到他在我发帖时添加了视图。我可以将其更改为匹配。
    • 无需更改,我已经可以正常使用了,谢谢!
    • 这正是您想要做的。令人惊讶的是,有多少主要网站未能执行成功提交后重定向操作。
    • 如何实现方法:some_form,我看不到任何内置API。 (django 1.9)
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      试一试

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

      而不是

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

      在我的情况下它工作得很好

      【讨论】:

        【解决方案4】:

        我找到了一种方法,我认为它适用于任何网站。您需要做的是添加一个 Htmx cdn,或者您可以从 htmx.org 调用 javascript 库,如 bootstrap 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/view,以便下次页面刷新时它会点击新的 url/view。

          【讨论】:

            【解决方案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 %}
            

            【讨论】:

              猜你喜欢
              • 2016-01-11
              • 2019-03-14
              • 2013-01-10
              • 2016-03-15
              • 2019-07-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多