9

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

我有一个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:并被重定向到与查询字符串相同的页面。但不显示错误消息。

我想要的是重定向到保留查询字符串的同一页面并显示错误消息。我在这里做错了什么以及建议进行哪些更改(如果有)。

还有一个疑问,Django 消息在重定向后真的像 Flash 消息一样有效吗?


编辑:

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 /user/edit-transaction/?object_id=23a959d0561711e59e36acd1b8679265&type=grossary HTTP/1.1”302 0 [16/Sep/2015 10:57:08]“GET /user/编辑事务/?object_id=23a959d0561711e59e36acd1b8679265&type=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 /user/edit-transaction/?object_id=23a959d0561711e59e36acd1b8679265&type=grossary HTTP/1.1”302 0

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

{% if messages %}在模板中,打印也没有进入<h1>I am inside MESSAGES</h1>

4

2 回答 2

25

终于想通了。在下面添加local_settings.py及其工作

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


发生了什么事 ?

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

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

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

什么是 FallbackStorage ?

这个类首先使用 CookieStorage,然后回退到使用 SessionStorage 来存储单个 cookie 中无法容纳的消息。它还需要 Django 的 contrib.sessions 应用程序。

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

在我的情况下发生了什么?

Messages被存储在 中CookiesStorage,但是由于某些奇怪的原因(我不知道是什么),但是对于第二个请求(即 POST 之后的重定向), MessagesinCookiesStorage已过期或被删除,这不应该发生(因为这不是如何flashdata工作的)。在我将默认设置切换为 之后MESSAGE_STORAGESessionStorage它开始工作。

于 2015-09-18T12:33:52.013 回答
1

在我的情况下,修改MESSAGE_STORAGE@ParagTyagi 提到的值是不够的。我有一些管理类的自定义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, "")

修改后,记得重启你的网络服务器(例如 Apache)并清除你的浏览器缓存。

于 2018-08-24T08:44:21.680 回答