在HttpResponseRedirect之后没有显示Django消息

时间:2015-09-16 05:32:56

标签: django django-messages

尝试了很多东西,但没有一个真的有帮助。

我有一个URL例如:

http://localhost:8000/user/edit-transaction/?object_id=23a959d0561711e59e36acd1b8679265&type=grossary

调用以下view

def edit_transaction(request):

    if request.method == "POST":
        if something is True:
            messages.error(request, 'Error message here')

            # this don't work
            return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

            # but this work
            template = "user/xyz/abc.html"
            render(request, template)
        else:
            return HttpResponseNotFound()
    else:
        context = {
             'key1': 'value1', 
             'key2': 'value2',
        }
        template = "user/xyz/abc.html"
        render(request, template, context)

在模板内:

{% if messages %}

<h1>I am inside MESSAGES</h1>

    {% for message in messages %}
        {% if message.tags == 'success' %}
            <div class="alert alert-success" role="alert">{{ message|escape|safe }}</div>
        {% elif message.tags == 'error' %}
            <div class="alert alert-danger" role="alert">{{ message|escape|safe }}</div>
        {% endif %}
    {% endfor %}
{% endif %}

它进入if这里if something is True:,并被重定向到同一页面,同时包含查询字符串。但不显示错误消息。

我想要的是重定向到保留查询字符串的同一页面并显示错误消息。我在这里做错了什么,推荐了哪些改变(如果有的话)。

  

同样值得怀疑的是,在Flash消息重定向之后,Django消息是否真的有效?

修改

1)这不起作用:

if something is True:
    messages.error(request, 'Error message here')
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

来自控制台:

  

[16 / Sep / 2015 10:57:08]“POST   /用户/编辑事务/的object_id = 23a959d0561711e59e36acd1b8679265&安培;键入= grossary   HTTP / 1.1“302 0 [16 / Sep / 2015 10:57:08]”GET   /用户/编辑事务/的object_id = 23a959d0561711e59e36acd1b8679265&安培;键入= grossary   HTTP / 1.1“200 8832

2)这有效:

if something is True:
    messages.error(request, 'Error message here')
    template = "user/xyz/abc.html"
    render(request, template)

来自控制台:

  

[16 / Sep / 2015 10:57:08]“POST   /用户/编辑事务/的object_id = 23a959d0561711e59e36acd1b8679265&安培;键入= grossary   HTTP / 1.1“302 0

所以,基本上我从上面了解到的是messages已经过期了一个额外的请求(重定向,200)。

在模板中,它不会进入{% if messages %}以打印<h1>I am inside MESSAGES</h1>

2 个答案:

答案 0 :(得分:15)

终于明白了。在local_settings.py及其正常工作中添加了以下内容。

MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'


发生了什么事?

消息实际上存储在 Cookies (CookieStorage)中,这是Django的默认行为。来自Django docs

  

FallbackStorage是默认存储类。如果不适合   您的需求,您可以通过设置选择另一个存储类   MESSAGE_STORAGE到其完整导入路径,例如:

     

MESSAGE_STORAGE =   'django.contrib.messages.storage.cookie.CookieStorage'

什么是FallbackStorage?

  

该类首先使用CookieStorage,然后再使用   SessionStorage用于无法放入单个cookie的消息。   它还需要Django的contrib.sessions应用程序。

     

此行为可以尽可能避免写入会话。它   应该在一般情况下提供最佳表现。

我的情况发生了什么?

Messages已存储在CookiesStorage中,但出于某种奇怪的原因(我不知道是什么),但Messages中的CookiesStorage已过期或已删除第二个请求(即POST后重定向)不应该发生(因为这不是flashdata的工作原理)。在我将默认MESSAGE_STORAGE切换为SessionStorage后,它就开始工作了。

答案 1 :(得分:0)

就我而言,仅修改@ParagTyagi提到的MESSAGE_STORAGE值是不够的。我为某些管理类使用了自定义change_list.html模板,在这些模板中,我必须添加以下代码:

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

请注意,我已经注释了<li>标签,否则消息将重复。

此外,messages对象中必须有多个消息。否则,消息也不会显示。如果您只显示一条消息(例如,确认操作成功),则只需添加另一条空消息,例如:

messages.add_message(self.request, messages.WARNING, "")

修改后,请记住重新启动Web服务器(例如Apache)并清除浏览器缓存。