【问题标题】:django display message after POST form submitPOST表单提交后django显示消息
【发布时间】:2015-04-27 16:44:24
【问题描述】:

我有一个带有 POST 表单的页面,其中有一个设置为某个 url 的操作。
即假设此页面网址为 /form_url/ : ..

/submit_url/ 中的视图负责处理表单数据。在此之后,我想返回带有成功消息的表单的同一页面。 在处理 POST 表单的视图中,我使用HttpResponseRedirect,以便从浏览器中“清除”表单数据。 但是通过这种方式,我无法在表单页面中显示消息,除非我执行以下操作:

return HttpResponseRedirect("/form_url/?success=1")

然后在模板中检查这个参数。我不喜欢这种方式,因为如果用户刷新页面,他仍然会看到成功消息。

我注意到在 django 管理站点中,对象的删除/添加确实在 POST 提交后使用重定向,并且仍然以某种方式显示成功消息。 怎么样?

我已经简要地看到过 django“消息传递”应用程序,但我想先了解它是如何工作的..

【问题讨论】:

    标签: django forms post message


    【解决方案1】:

    对于基于类的视图,使用 self.request

    我也使用 self.request.path_info 在我的回报

    from django.contrib import messages
    
    class MyCreateView(CreateView):
        ...
           def form_valid(self, form):
              ....
              self.object.save()
    
              messages.success(self.request, 'Form submission successful')
              
              return HttpResponseRedirect(self.request.path_info)
    

    与 damio 的答案相同的模板:

    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li  {% if message.tags %} class=" {{ message.tags }} " {% endif %}> {{ message }} </li>
        {% endfor %}
    </ul>
    {% endif %}
    

    【讨论】:

      【解决方案2】:

      django 管理员使用django.contrib.messages,你可以这样使用:

      在你看来:

      from django.contrib import messages
      
      def my_view(request):
          ...
             if form.is_valid():
                ....
                messages.success(request, 'Form submission successful')
      

      在您的模板中:

      {% if messages %}
      <ul class="messages">
          {% for message in messages %}
          <li  {% if message.tags %} class=" {{ message.tags }} " {% endif %}> {{ message }} </li>
          {% endfor %}
      </ul>
      {% endif %}
      

      【讨论】:

        【解决方案3】:
        from django.contrib.messages.views import SuccessMessageMixin
        from django.views.generic.edit import CreateView 
        from myapp.models import Author
        
        class AuthorCreate(SuccessMessageMixin, CreateView):
            model = Author
            success_url = '/success/'
            success_message = "%(name)s was created successfully"
        

        https://docs.djangoproject.com/en/1.11/ref/contrib/messages/

        【讨论】:

          【解决方案4】:

          您无需执行重定向即可清除表单数据。您需要做的就是重新实例化表单:

          def your_view(request):
              form = YourForm(request.POST or None)
              success = False
              if request.method == 'POST':
                  if form.is_valid():
                      form.save()
                      form = YourForm()
                      success = True
              return render(request, 'your_template.html', {'form': form})
          

          如果用户刷新页面,他们将发起一个 GET 请求,success 将是False。无论哪种方式,表单都会在 GET 或成功的 POST 上解除绑定。

          如果您利用messages framework,您仍然需要在模板中添加一个条件来显示消息是否存在。

          【讨论】:

          • 如果我使用 render() 从 POST 请求的视图返回响应,那么如果用户刷新页面,浏览器将提示是否再次发送表单。这就是我要避免的。
          • 你在这里真的别无选择。您要么需要发出重定向并传递查询字符串参数,要么需要使用消息/会话值。
          • django消息应用使用后是否清除会话数据?由于显示后不需要保存会话。
          • 是的。每个请求周期每条消息仅显示一次。
          【解决方案5】:

          Django 消息框架将消息存储在会话或 cookie 中(取决于storage backend)。

          【讨论】:

          • 我明白了。我是这么想的。我正在尝试在不使用会话的情况下执行此操作。