请求完成后,有时需要让用户知道状态发生了变化,可以是确认消息、警告或者错误提醒。一个典型例子是,用户提交有一项错误的登录表单后,服务器发回的响应重新渲染登录表单,并在表单上面显示一个消息,提示用户名或密码无效。

Flask 提供了一个非常简单的方法来使用闪现系统向用户反馈信息。闪现系统在一个请求结束的时候记录一个信息,然后仅在下一个请求中访问这个数据。

发送闪现消息

  1. def flash(message, category="message"):
  2. # Original implementation:
  3. #
  4. # session.setdefault('_flashes', []).append((category, message))
  5. #
  6. # This assumed that changes made to mutable structures in the session are
  7. # always in sync with the session object, which is not true for session
  8. # implementations that use external storage for keeping their keys/values.
  9. flashes = session.get("_flashes", [])
  10. flashes.append((category, message))
  11. session["_flashes"] = flashes
  12. message_flashed.send(
  13. current_app._get_current_object(), message=message, category=category
  14. )

首先从 session 获取 _flashes 键对应的消息列表,如果没有获取到将创建空列表作为默认值,然后将 messagecategory 作为元组添加到这个列表,最后再次将消息列表以 _flashes 作为键存入 session 中,最后通过 message_flashed 在消息闪现后发送一个信号

任何字符串都可以用作类别,category 建议使用以下值:对于任何类型的消息,均使用“ message”,对于错误,使用“ error”,对信息消息使用“ info”,对警告使用“ warning”

原始版本使用 session.setdefault('_flashes', []).append((category, message)),但是当使用外部存储保存会话的键值对时,修改会话中可变对象的值可能不会与会话对象保持同步,所以需要显示赋值进行同步

获取闪现消息

  1. def get_flashed_messages(with_categories=False, category_filter=()):
  2. flashes = _request_ctx_stack.top.flashes
  3. if flashes is None:
  4. _request_ctx_stack.top.flashes = flashes = (
  5. session.pop("_flashes") if "_flashes" in session else []
  6. )
  7. if category_filter:
  8. flashes = list(filter(lambda f: f[0] in category_filter, flashes))
  9. if not with_categories:
  10. return [x[1] for x in flashes]
  11. return flashes

首先是从 _request_ctx_stack.top.flashes (请求上下文堆栈的顶部)获取闪现的消息,如果没有获取到,那么再从 session 对象里获取。如果设置了 category_filter (按类别过滤,只返回指定类别的的消息)和 with_categories (控制是否返回消息类别)参数,那么则对消息列表进行相应修改,最后返回消息列表。

获取的消息在下次调用时不会再次返回,因此闪现消息只显示一次,然后就消失了。