Django提交表单后显示消息

34

我有一个带有POST表单的页面,它的操作设置为某个URL。
例如假设此页面URL为/form_url/:

视图/submit_url/负责处理表单数据。完成后,我希望返回相同的表单页面,并显示成功消息。 在处理POST表单的视图中,我使用HttpResponseRedirect来“清除”浏览器中的表单数据。 但是这样做无法在表单页面上显示消息,除非我做类似以下的操作:

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

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

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

我已经简要了解了Django的“消息”应用程序,但首先我想知道它是如何工作的..

6个回答

70
django管理界面使用django.contrib.messages,你可以像这样使用它:
在你的视图(view)中:
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 %}

12

对于类视图,请使用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 %}

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


6
您不需要执行重定向来清除表单数据。您只需要重新实例化表单即可:
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上,表单都将解除绑定。
如果你利用消息框架,你仍然需要在模板中添加条件来显示消息是否存在。

4
如果我在视图中使用render()函数返回一个POST请求的响应,那么如果用户刷新页面,浏览器会弹出提示框询问是否重新发送表单。这正是我想要避免的。 - user3599803
你在这里真的没有太多选择。你要么需要发出重定向并传递查询字符串参数,要么需要使用消息/会话值。 - Brandon Taylor
Django消息应用程序在使用后是否清除会话数据?因为在显示会话后没有保存会话的必要。 - user3599803
是的。每个消息在请求周期内只显示一次。 - Brandon Taylor

5

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


我明白了。我也是这么想的。我正在尝试在不使用会话的情况下完成这个任务。 - user3599803

0
如果你在使用 Django 的类视图和表单时,确认你已经设置好了 messages.html 模板,那么你可以像下面这样将 'SuccessMessageMixin' 传递给你的视图。
class YourView(SuccessMessageMixin,View):
        success_message = 'your message_here'

这将在表单成功时显示您的消息


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接