Flask 大型教程,第21部分:用户通知

Flask 大型教程,第21部分:用户通知

💡 原文英文,约4300词,阅读约需16分钟。
📝

内容提要

第21章介绍为Microblog添加私信功能:用户可在他人资料页发送私信,导航栏新增“Messages”链接查看收件箱,并记录最后阅读时间以统计未读数;随后在导航栏加入未读消息徽章,并通过JavaScript定时轮询/notifications接口,实现无需刷新页面即可自动更新未读消息数量。

🔎

延伸解读

私信功能的数据模型设计

本章为私信功能新增了Message模型,包含发送者、接收者、正文和时间戳字段。User模型通过last_message_read_time记录最后阅读时间,并利用unread_message_count()方法统计未读消息数。这种设计将已读状态与用户关联,而非逐条标记消息,简化了数据库操作,但也意味着用户一旦访问消息页面,所有历史消息都会被标记为已读。

静态与动态通知徽章的对比

静态徽章在页面加载时通过模板调用unread_message_count()渲染,实现简单但无法实时更新。动态徽章则始终包含在导航栏中,通过CSS控制可见性,并借助JavaScript定时轮询/notifications接口更新计数。动态方案提升了用户体验,但引入了最多10秒的延迟,且需要额外的客户端脚本和服务器端点。

轮询与WebSocket的取舍

文章对比了两种通知推送方式:轮询和WebSocket。轮询实现简单,兼容现有HTTP架构,但存在延迟;WebSocket能实现零延迟推送,但需要维护持久连接,对服务器资源消耗大,且配置复杂。作者选择轮询方案,认为对于此类应用已足够,并指出Twitter等大型网站也采用类似轮询的机制。

通知系统的可扩展性设计

通知被抽象为通用的Notification模型,包含名称、用户、时间戳和JSON负载。add_notification()方法会先删除同名旧通知再添加新通知,确保每个用户每种通知只保留最新一条。这种设计便于未来扩展其他类型的通知,而不仅限于未读消息计数。

❓

Q&A

Flask Mega-Tutorial 第21章主要实现了什么功能?

本章为 Microblog 应用添加了私信功能,并实现了导航栏中的未读消息通知徽章,该徽章无需刷新页面即可自动更新。

如何在 Flask 应用中实现私信功能?

需要扩展数据库,添加 Message 模型(包含 sender_id、recipient_id、body、timestamp 字段),在 User 模型中添加 last_message_read_time 字段和 messages_sent、messages_received 关系,以及 unread_message_count() 方法。然后创建发送私信的表单和路由 /send_message/<recipient>,以及查看私信的 /messages 路由,并在导航栏添加 Messages 链接。

未读消息数量是如何计算的?

通过 User 模型的 unread_message_count() 方法计算。该方法使用 last_message_read_time 字段(用户上次访问消息页的时间),查询所有 recipient 为当前用户且 timestamp 晚于该时间的 Message 记录,并返回计数。如果 last_message_read_time 为空,则默认从 1900 年 1 月 1 日开始计算。

如何让未读消息徽章动态更新而无需刷新页面?

使用 JavaScript 定时轮询。在 base.html 中定义一个 set_message_count() 函数来更新徽章数字和可见性,然后使用 setInterval() 每 10 秒通过 fetch() 请求 /notifications 接口,获取自上次请求以来的新通知。当收到 unread_message_count 通知时,调用 set_message_count() 更新徽章。

服务器向客户端推送通知有哪两种方式?各有什么优缺点?

第一种是客户端定期轮询(如每10秒请求一次 /notifications),实现简单但通知有延迟;第二种是使用 WebSocket 建立持久连接,服务器可主动推送,无延迟,但需要更复杂的设置,且服务器能同时处理的连接数远少于 HTTP。

Notification 模型包含哪些字段?

Notification 模型包含 id(主键)、name(通知名称,字符串)、user_id(外键关联用户)、timestamp(Unix 时间戳,默认 time.time())、payload_json(JSON 格式的负载数据)字段,以及 user 关系。还提供了 get_data() 方法用于反序列化 JSON 负载。

如何测试未读消息通知功能?

使用两个不同的浏览器,分别以不同用户登录 Microblog。从一个浏览器向另一个用户发送一条或多条私信,另一个浏览器的导航栏应在 10 秒内更新显示未读消息数量。点击 Messages 链接后,未读计数应重置为零。

🏷️

标签

➡️

继续阅读