在 Django 中构建灵活的通知系统:综合指南
来源:dev.to
2024-12-29 09:10:02
0浏览
收藏
IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《在 Django 中构建灵活的通知系统:综合指南》,聊聊,我们一起来看看吧!
通知是任何现代 web 应用程序的关键组成部分,可确保用户了解情况并参与其中。实施良好的通知系统可以处理多个渠道,例如应用内警报、电子邮件和短信,同时动态定制内容以实现无缝的用户体验。在本指南中,我们将引导您在 django 中创建一个强大的、可扩展的通知系统。
系统功能
我们的通知系统旨在提供:
- 支持多渠道:通过应用内提醒、电子邮件或短信发送通知。
- 动态内容个性化:带有占位符的模板,用于生成个性化消息。
- 基于事件的触发器:根据特定系统或用户事件触发通知。
- 状态跟踪:监控电子邮件和短信通知的传送状态。
- 管理和系统集成:通知可以由管理员或系统事件触发。
定义模型
1.通知模板
模板是我们系统的支柱,存储可重复使用的通知内容。
from django.db import models class channeltype(models.textchoices): app = 'app', 'in-app notification' sms = 'sms', 'sms' email = 'email', 'email' class triggeredbytype(models.textchoices): system = 'system', 'system notification' admin = 'admin', 'admin notification' class triggerevent(models.textchoices): enrollment = 'enrollment', 'enrollment' announcement = 'announcement', 'announcement' promotional = 'promotional', 'promotional' reset_password = 'reset_password', 'reset password' class notificationtemplate(models.model): title = models.charfield(max_length=255) template = models.textfield(help_text='use placeholders like {{username}} for personalization.') channel = models.charfield(max_length=20, choices=channeltype.choices, default=channeltype.app) triggered_by = models.charfield(max_length=20, choices=triggeredbytype.choices, default=triggeredbytype.system) trigger_event = models.charfield(max_length=50, choices=triggerevent.choices, help_text='event that triggers this template.') is_active = models.booleanfield(default=true) created_at = models.datetimefield(auto_now_add=true) updated_at = models.datetimefield(auto_now=true)
主要特点:
- 模板:带有动态值占位符的文本,例如 {{username}}.
- 渠道:指定是电子邮件、短信还是应用内通知。
- trigger_event:将模板与特定事件关联。
2.一般通知
通知模型将模板链接到用户并存储任何动态负载以进行个性化。
class notification(models.model): user = models.foreignkey(user, on_delete=models.cascade, related_name="notifications") content = models.foreignkey(notificationtemplate, on_delete=models.cascade, related_name="notifications") payload = models.jsonfield(default=dict, help_text="data to replace template placeholders.") is_read = models.booleanfield(default=false) created_at = models.datetimefield(auto_now_add=true)
3.特定于渠道的模型
为了独特地处理电子邮件和短信,我们定义了特定的模型。
电子邮件通知
该模型管理特定于电子邮件的数据,例如动态消息生成和传递跟踪。
class statustype(models.textchoices): pending = 'pending', 'pending' success = 'success', 'success' failed = 'failed', 'failed' class emailnotification(models.model): user = models.foreignkey(user, on_delete=models.cascade, related_name='email_notifications') content = models.foreignkey(notificationtemplate, on_delete=models.cascade, related_name='email_notifications') payload = models.jsonfield(default=dict) status = models.charfield(max_length=20, choices=statustype.choices, default=statustype.pending) status_reason = models.textfield(null=true) @property def email_content(self): """ populate the template with dynamic data from the payload. """ content = self.content.template for key, value in self.payload.items(): content = re.sub( rf"{{{{\s*{key}\s*}}}}", str(value), content, ) return content
短信通知
与电子邮件通知类似,这里实现了短信特定逻辑。
class smsnotification(models.model): user = models.foreignkey(user, on_delete=models.cascade, related_name='sms_notifications') content = models.foreignkey(notificationtemplate, on_delete=models.cascade, related_name='sms_notifications') payload = models.jsonfield(default=dict) status = models.charfield(max_length=20, choices=statustype.choices, default=statustype.pending) status_reason = models.textfield(null=true) @property def sms_content(self): """ populate the template with dynamic data from the payload. """ content = self.content.template for key, value in self.payload.items(): content = re.sub( rf"{{{{\s*{key}\s*}}}}", str(value), content, ) return content
管理集成
为了更轻松地管理通知,我们在 django 管理面板中注册模型。
from django.contrib import admin from notifier.models import notificationtemplate @admin.register(notificationtemplate) class notificationtemplateadmin(admin.modeladmin): list_display = ['title', 'channel', 'triggered_by', 'trigger_event', 'is_active'] list_filter = ['channel', 'triggered_by', 'is_active'] search_fields = ['title', 'trigger_event']
通知服务
我们将实现一个服务层来管理通过各种渠道发送通知。
策略模式
使用策略模式,我们将为每个通知通道定义类。
from abc import abc, abstractmethod import logging logger = logging.getlogger(__name__) class notificationstrategy(abc): @abstractmethod def send(self, user, content, payload): pass class appnotificationstrategy(notificationstrategy): def send(self, user, content, payload): notification = notification.objects.create(user=user, content=content, payload=payload) logger.info(f"in-app notification sent to {user.email}") return notification class emailnotificationstrategy(notificationstrategy): def send(self, user, content, payload): notification = emailnotification.objects.create(user=user, content=content, payload=payload) try: self._send_email(user.email, content.title, notification.email_content) notification.status = "success" except exception as e: notification.status = "failed" notification.status_reason = str(e) notification.save() return notification def _send_email(self, to_email, subject, body): print(f"sending email to {to_email} with subject {subject}") if "@" not in to_email: raise valueerror("invalid email address") class smsnotificationstrategy(notificationstrategy): def send(self, user, content, payload): notification = smsnotification.objects.create(user=user, content=content, payload=payload) try: self._send_sms(user.phone_number, notification.sms_content) notification.status = "success" except exception as e: notification.status = "failed" notification.status_reason = str(e) notification.save() return notification def _send_sms(self, phone_number, message): print(f"sending sms to {phone_number}: {message}") if not phone_number.isdigit(): raise valueerror("invalid phone number")
通知服务
该服务将所有内容联系在一起,根据通知渠道选择适当的策略。
class notificationservice: _strategies: dict[type[channeltype], type[notificationstrategy]] = { channeltype.app: appnotificationstrategy, channeltype.email: emailnotificationstrategy, channeltype.sms: smsnotificationstrategy, } @classmethod def get_strategy(cls, instance: notificationtemplate) -> notificationstrategy: try: channel = channeltype[instance.channel] strategy = cls._strategies[channel] except keyerror: raise exception(f"unknown notification strategy {instance.channel}") return strategy() @classmethod def notify( cls, user: user, event: triggerevent, payload: dict, ): """ automatically create and send a system-triggered notification. args: user: user instance. event: triggerevent type. payload: dynamic `dict` data for the notification. returns: result of the notification strategy. """ content, _ = notificationtemplate.objects.get_or_create( trigger_event=event, triggered_by=triggeredbytype.system, defaults={ "title": 'default title', "template": "this is a system notification.", }, ) strategy = cls.get_strategy(instance=content) return strategy.send(user, content, payload)
使用示例
以下是如何使用通知服务:
from notifier.services import NotificationService, TriggerEvent user = User.objects.get(email="user@example.com") payload = {"username": "John Doe", "course": "Python Basics"} NotificationService.notify(user, TriggerEvent.USER_ENROLLED, payload)
如果您发现本指南很有帮助且富有洞察力,请不要忘记点赞并关注以获取更多此类内容。您的支持激励我分享更多实用的实现和深入的教程。让我们继续一起构建令人惊叹的应用程序!
终于介绍完啦!小伙伴们,这篇关于《在 Django 中构建灵活的通知系统:综合指南》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!
版本声明
本文转载于:dev.to 如有侵犯,请联系study_golang@163.com删除

- 上一篇
- 如何正确填写电脑验光单?

- 下一篇
- 为什么这段 JavaScript 代码中的 `i` 始终输出 6?
查看更多
最新文章
-
- 文章 · python教程 | 14分钟前 |
- PyCharm能汉化吗?中文支持详细教程
- 304浏览 收藏
-
- 文章 · python教程 | 8小时前 |
- Pythonupper函数怎么用?轻松实现字符串大写转换!
- 416浏览 收藏
-
- 文章 · python教程 | 8小时前 |
- PyCharm安装傻瓜式教程|配置选项全推荐
- 261浏览 收藏
-
- 文章 · python教程 | 8小时前 |
- 手把手教学!超详细的数据类型转换全攻略
- 377浏览 收藏
-
- 文章 · python教程 | 8小时前 |
- Python中的str是什么?手把手教你搞定字符串类型
- 485浏览 收藏
-
- 文章 · python教程 | 9小时前 |
- 手把手教学!小白也能轻松学会配置Python环境变量
- 383浏览 收藏
-
- 文章 · python教程 | 9小时前 |
- Python格式化字符串全解|format函数超详细用法
- 222浏览 收藏
-
- 文章 · python教程 | 9小时前 |
- Python中@property装饰器的正确使用姿势
- 443浏览 收藏
-
- 文章 · python教程 | 9小时前 |
- 手把手教学!Python程序写完后怎么运行?超详细步骤全流程揭秘
- 188浏览 收藏
-
- 文章 · python教程 | 9小时前 |
- Pythonglobal关键字怎么用?全局变量声明超简单教程
- 310浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
查看更多
AI推荐
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 56次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 74次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 84次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 76次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 80次使用
查看更多
相关文章
-
- Flask框架安装技巧:让你的开发更高效
- 2024-01-03 501浏览
-
- Django框架中的并发处理技巧
- 2024-01-22 501浏览
-
- 提升Python包下载速度的方法——正确配置pip的国内源
- 2024-01-17 501浏览
-
- Python与C++:哪个编程语言更适合初学者?
- 2024-03-25 501浏览
-
- 品牌建设技巧
- 2024-04-06 501浏览