起步

20200106114331.png

网站往往需要对用户的操作进行一定的提示。它的特点是即时的,一次性的,有等级的。消息不是在请求处理完后销毁的,而是在消息展示后销毁的,也就是说它需要有临时存储的能力。

Django 内置的消息框架就是来处理这样的业务需求。

启用

消息框架默认是启用的,确认下 INSTALLED_APPS 是否有 django.contrib.messages ;以及中间件是否有 django.contrib.messages.middleware.MessageMiddleware 。这样就满足使用的条件了。

使用

消息框架提供了 5 种消息级别:

消息 含义 样式 级别
DEBUG 将在生产部署中忽略(或删除)的与开发相关的消息 debug 10
INFO 给用户的提示信息 info 20 (默认)
SUCCESS 操作成功 success 25
WARNING 警告信息 warning 30
ERROR 已经发生的错误信息 error 40

每个消息都需要指定它的等级,样式则是在前端用于设置在css的类里。可以通过在 settings.py 设置 MESSAGE_LEVEL 设置可用的最小级别,级别低于这个设置的消息会被忽略。

添加消息

提供的api:add_message(request, level, message, extra_tags='', fail_silently=False)

from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')

也可以通过快捷的函数进行设置:

messages.debug(request, '%s SQL statements were executed.' % count)
messages.info(request, 'Three credits remain in your account.')
messages.success(request, 'Profile details updated.')
messages.warning(request, 'Your account expires in three days.')
messages.error(request, 'Document deleted.')

前端显示

在末班中,类似这样的内容就可以展示:

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

messages 可以在模板里直接使用,它不需要开发者手动注入变量,启用消息框架后就会自动注入到模板上下文处理器了。

存储后端

消息需要临时存放的地方。框架提供了三个内置的存储类:

  • storage.session.SessionStorage:消息存在会话中。需要 contrib.sessions 支持。
  • storage.cookie.CookieStorage:消息存放在cookie中,cookie会做签名处理。由于cookie存储容量有限,因此消息若超过2KB,则丢弃旧消息。
  • storage.fallback.FallbackStorage: 这个是默认的存储类。它优先使用 CookieStorage ,如果消息量过大,它会回退到使用 SessionStorage 来处理无法容纳的消息。

修改存储后端也是通过配置 settings.py 来完成:

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

自定义消息级别

定义消息级别的文件在 django.contrib.message.constants 中:

# constants.py
DEBUG = 10
INFO = 20
SUCCESS = 25
WARNING = 30
ERROR = 40

可以看到,消息级别不过是整数,因此可以容易自定义级别,比如:

CRITICAL = 50

def my_view(request):
    messages.add_message(request, CRITICAL, 'A serious error occurred.')

如果需要在 CSS 中标识自定义的级别,应该通过 MESSAGE_TAGS 设置映射规则。

动态修改最低级别记录

可以通过 set_level 方法为每个请求设置最低记录的级别:

from django.contrib import messages
messages.set_level(request, messages.DEBUG)
messages.set_level(request, None)  # 使用默认设置

current_level = messages.get_level(request) # 获取当前的级别表示的整数

消息过期

消息会在迭代过程中设置清除标记,并在处理 response 时清除。若要避免这种情况,需要手动指定:

storage = messages.get_messages(request)
for message in storage:
    do_something_with(message)
storage.used = False

并发提醒

因为存储是基于 cookie 或 session 的,由于他们的工作方式,如果同一个客户端同时发出多个请求时,消息框架里的消息的行为是不确定的。因此,当涉及同一个客户端并发请求时,不能保证消息传递到同一个窗口中,也可能某些请求下根本不传递消息。在绝大多数请求下,这不算是什么问题。

总结

内置的消息框架适合的应用场景是。一次性的通知消息即(即时消息);消息在没被使用的情况下能延续到下一个请求中;消息拥有级别属性;对并发要求不高。


本文由 hongweipeng 创作,采用 署名-非商业性使用-相同方式共享 3.0,可自由转载、引用,但需署名作者且注明文章出处。

如果对您有用,您的支持将鼓励我继续创作!