在网页应用中,我们经常需要在处理完表单或其它类型的用户输入后,显示一个通知信息给用户。

对于这个需求,Django提供了基于Cookie或者会话的消息框架messages,无论是匿名用户还是认证的用户。这个消息框架允许你临时将消息存储在请求中,并在接下来的请求(通常就是下一个请求)中提取它们并显示。每个消息都带有一个特定的level标签,表示其优先级(例如info、 warning或error)。

一、启用消息框架

Django的messages消息框架的实现,依赖messages中间件和对应的context processor。

通过django-admin startproject xxx命令创建工程时,已经默认在settings.py中开启了消息框架功能需要的所有的设置:

  • INSTALLED_APPS中注册的'django.contrib.messages'。

  • MIDDLEWARE中添加'django.contrib.sessions.middleware.SessionMiddleware'和'django.contrib.messages.middleware.MessageMiddleware'。Django的messages框架默认使用的存储后端为sessions。所以Session中间件必须被启用,并出现在Message中间件之前。

  • TEMPLATES设置中的DjangoTemplates选项包含的'context_processors'配置项要包含'django.contrib.messages.context_processors.messages'。

二、配置消息引擎

通常我们使用默认的就好,可以跳过这节,但如果真有需要,也可以配置:

1. 存储后端

Django提供了三种内置的消息存储后端:

class storage.session.SessionStorage class storage.cookie.CookieStorage class storage.fallback.FallbackStorage

FallbackStorage是默认的存储后端。如果它不适合你的需要,你可以通过设置MESSAGE_STORAGE选择另外一个存储后端,例如:

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

2. 消息级别

消息框架的级别是可配置的,与Python的logging模块类似

Django内置的message级别有下面几种:

级别 说明
DEBUG 将在生产部署中忽略(或删除)的与开发相关的消息
INFO 普通提示信息
SUCCESS 成功信息
WARNING 警告信息
ERROR 已经发生的错误信息

MESSAGE_LEVEL设置可以用来改变记录的最小级别(参考前面的Django设置章节),小于这个级别的消息将被忽略。

3. 消息样式

通常,我们在前端HTML页面中,希望给不同级别的消息,增加不同的CSS样式,比如警告为黄色,error为红色等等。

Django为我们提供了一个默认的样式对应关系:

级别 样式
DEBUG debug
INFO info
SUCCESS success
WARNING warning
ERROR error

也就是说SUCCESS级别的消息,在前端会被赋予一个success样式class。

若要修改消息级别的默认样式,设置MESSAGE_TAGS,按如下例子所示:。

from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
messages.INFO: '',
50: 'critical',
}

三、使用消息框架

1. 添加消息

方法原型:add_message(request, level, message, extra_tags='', fail_silently=False)[source]

新增一条消息:

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

提供请求对象request(直接用就行),消息级别、消息内容字符串三个参数即可。

或者使用下面的快捷方式

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.')

2. 显示消息

方法原型:get_messages(request)[source]

在你的模板文件中,像下面这样使用:

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

相关说明:

  • 通过if判断是否有消息;
  • messages是一个列表,必须用for标签循环它;
  • 即使你知道只有一条消息,也要迭代messages列表,否则下个请求中,上个请求的消息不会被清除。
  • 可以通过message.tags拿到每个消息的CSS样式

有一个DEFAULT_MESSAGE_LEVELS变量,它映射消息级别的名称到它们的数值:

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

说明:

  • 可以通过message.level拿到当前消息的级别数值;
  • 将它与DEFAULT_MESSAGE_LEVELS.ERROR进行对比;
  • 如果一样,就说明当前消息级别为ERROR,需要显示到页面上。

在模板的外面,比如视图中,可以使用get_messages()方法获取消息:

from django.contrib.messages import get_messages

storage = get_messages(request)
for message in storage:
do_something_with_the_message(message)

说明:

  • get_messages()返回的是存储后端的一个实例。
  • 循环这个实例,可以获得每条消息

对于每一个消息实例,都包含下面的属性,可以在模版或视图中调用:

  • message: 消息的实际内容文本。不要使用message.message,直接message。
  • level: 消息级别,一个整数。
  • tags: 一个字符串,由该消息的所有标签(extra_tags和tags)组合而成,组合时用空格分割开这些标签。
  • extra_tags: 一个字符串,由该消息的定制标签组合而成,并用空格分割。默认为空。
  • level_tag: 当前消息级别对应的CSS字符串,前面介绍过。

3. 自定义消息级别

消息级别只是一个整数常量,所以,可以定义自己的级别常量,例如:

CRITICAL = 50

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

在自定义消息级别时,应小心避免覆盖现有级别。内置级别的值为:

级别 对应整数值
DEBUG 10
INFO 20
SUCCESS 25
WARNING 30
ERROR 40

如果你需要在HTML或CSS中使用自定义级别,则需要通过MESSAGE_TAGS设置提供相应的映射关系。

4. 自定义每个请求的最小记录级别

每个请求都可以通过set_level()方法设置最小记录级别,如下所示:

from django.contrib import messages

# 修改最小级别为DEBUG
messages.set_level(request, messages.DEBUG)
messages.debug(request, 'Test message...') # 在另外一个视图中修改最小级别为WARNING
messages.set_level(request, messages.WARNING)
messages.success(request, 'Your profile was updated.') # 被忽略,不记录
messages.warning(request, 'Your account is about to expire.') # 记录 # 将最小级别恢复到默认值
messages.set_level(request, None)

set_level()方法接收request为第一参数,消息级别为第二参数。

类似的,当前有效的记录级别可以用get_level()方法获取:

from django.contrib import messages
current_level = messages.get_level(request)

5. 添加额外的消息CSS样式

要添加自定义的消息CSS样式,可以通过extra_tags参数:

messages.add_message(request, messages.INFO, 'Over 9000!', extra_tags='dragonball')
messages.error(request, 'Email box full', extra_tags='email')

四、消息过期机制

默认情况下,如果包含消息的迭代器完成迭代后,当前请求中的消息都将被删除。

如果你不想这么做,想保留这些消息,那么需要显式的指定used参数为False,如下所示:

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

django 消息框架 message的更多相关文章

  1. 第六章:Django 综合篇 - 10:消息框架 message

    在网页应用中,我们经常需要在处理完表单或其它类型的用户输入后,显示一个通知信息给用户. 对于这个需求,Django提供了基于Cookie或者会话的消息框架messages,无论是匿名用户还是认证的用户 ...

  2. Django messages框架

    一.简介 在网页应用中,你经常需要在处理完表单或其它类型的用户输入后,显示一个通知消息(也叫做“flash message”)给用户 对于这个功能,Django 提供基于Cookie 和会话的消息,无 ...

  3. WCF技术剖析之十七:消息(Message)详解(上篇)

    原文:WCF技术剖析之十七:消息(Message)详解(上篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]消息交换 ...

  4. 记Angular与Django REST框架的一次合作(2):前端组件化——Angular

    注:这是这个系列的第二部分,主要集中在Angular的使用方面.之前使用过AngularJS(Angular 1.x),混在Django的模板中使用,这些页面一般完全是结果展示页.在有Django表单 ...

  5. 教程:Visual Studio 中的 Django Web 框架入门

    教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...

  6. C++消息框架-基于sigslot

    目录 一.简介 二.消息 三.发送者 1.发送消息函数 2.新增一个接收者函数 3.移除一个接收者函数 四.接收者 五.功能测试 1.消息接收类 2.测试代码 3.测试结果 六.源码 一.简介 上一篇 ...

  7. 代码的坏味道(20)——过度耦合的消息链(Message Chains)

    坏味道--过度耦合的消息链(Message Chains) 特征 消息链的形式类似于:obj.getA().getB().getC(). 问题原因 如果你看到用户向一个对象请求另一个对象,然后再向后者 ...

  8. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  9. WCF技术剖析之十七:消息(Message)详解(下篇)

    原文:WCF技术剖析之十七:消息(Message)详解(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]< ...

随机推荐

  1. Python进阶【第八篇】迭代器和生成器

    一.何谓迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration).迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代 ...

  2. hibernate文档头的不同版本

    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "h ...

  3. SRTP参数及数据包处理过程(转)

    源: SRTP参数及数据包处理过程

  4. php 获取文件后缀

    /** * 获取文件后缀 * $path 本地存储临时文件路径 * */ private function getFileType($path){ $fp=fopen($path,'r'); $bin ...

  5. Centos环境自写脚本查看使用php或nginx占用内存

    在CentOs6.4下,用root权限测试. # cd ~ //进入home目录 # vim .bashrc //编辑文件,把下面代码放入地址 mem () { top -n1 -b | head - ...

  6. Vue小案例 之 商品管理------批量删除与商品数量的调整

    通过索引进行删除,进行测试,是否获取其索引: 测试效果: 测试代码,在vue中定义一个空的数组,以便后面进行数据的绑定: data:{ imgUrl:'../res/images/', imgName ...

  7. Caused by: com.rabbitmq.client.ShutdownSignalException: connection error

    周五下午的时候升级了一个环境,跑了批处理sh升级脚本后,启动时报下列错误: INFO | jvm 1 | 2017/02/24 17:39:09 | java.io.IOException INFO ...

  8. Codeforces 832E Vasya and Shifts - 高斯消元

    题目传送门 快速的传送门I 快速的传送门II 题目大意 (题意比较复杂,请自行阅读原题) 可以将原题的字母都看成它们的在字符表中的下标,这样问题就变成给定$n$个$m$维向量$\vec{a_{1}}, ...

  9. NOIP 车站分级 (luogu 1983 & codevs 3294 & vijos 1851) - 拓扑排序 - bitset

    描述 一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车 ...

  10. 【Python028--引入文件】

    一.打开文件 1.open()函数 打开模式 执行操作 ‘r’ 以只读方式打开文件(默认) ‘w’ 以写入的方式打开文件,会覆盖已存在的文件 ‘x’     如果文件已经存在,使用此模式打开将引发异常 ...