Django如何实现允许用户自定义含变量标签的邮件模板且后端自动填充值
Django用户自定义邮件模板实现方案
1. 前端编辑器部分
- 可选择轻量的纯文本编辑器/富文本编辑器,按需支持纯文本或HTML格式邮件编写
- 将系统预设允许使用的变量做成可点击的快捷插入按钮,用户点击即可自动插入对应格式的占位符,无需手动输入,减少变量名错误概率
- 可选增加实时预览功能,前端代入模拟数据提前给用户展示渲染后的效果
2. 后端存储与校验
- 新增模板存储模型,核心字段参考:
- 模板名称
- 模板原始内容
- 创建者/所属用户
- 允许使用的变量范围(可选,用于提交校验)
- 创建/更新时间
- 用户提交模板时做合法性校验:检测所有用户输入的占位符是否在系统开放的变量列表内,拒绝包含未授权变量的模板提交
- 统一占位符格式,推荐两种可选规范:
- 简单场景用
<变量名>格式,比如<employee name> - 需要扩展功能用
{{ 变量名 }}格式,符合Django原生模板变量规则
- 简单场景用
3. 模板渲染逻辑
根据你的功能复杂度二选一即可:
轻量字符串替换方案(无逻辑需求首选)
仅需简单变量替换的场景,用正则匹配实现即可,性能高、风险低:
import re from typing import Dict def render_simple_template(raw_template: str, context: Dict) -> str: # 匹配所有<变量名>格式的占位符 placeholders = re.findall(r"<([a-zA-Z\s]+)>", raw_template) result = raw_template for ph in placeholders: # 把占位符里的空格转为下划线匹配上下文字典的key context_key = ph.strip().replace(" ", "_") if context_key in context: result = result.replace(f"<{ph}>", str(context[context_key])) return result
调用示例:
template = "Hi, <employee name>\n\nI am very happy to inform you that you have been confirmed for the position of <position name> for the upcoming <project_type> <project_name>...." context = { "employee_name": "Mike", "position_name": "Product Designer", "project_type": "feature film", "project_name": "Titanic" } final_content = render_simple_template(template, context)
扩展功能方案(支持简单逻辑)
如果需要支持条件判断、循环这类轻量模板逻辑,用Django原生模板引擎加沙箱限制实现:
from django.template import Engine, Context def render_advance_template(raw_template: str, context: Dict) -> str: # 自定义受限模板引擎,禁用危险标签、关闭调试 safe_engine = Engine( debug=False, autoescape=True, string_if_invalid="", loaders=[], allowed_include_roots=[] ) template = safe_engine.from_string(raw_template) return template.render(Context(context))
4. 安全注意事项
- 禁止开放Django原生的
{% %}模板标签权限,避免模板注入漏洞 - 如果支持HTML格式的邮件,渲染完成后必须通过XSS过滤工具清理危险标签和事件属性
- 不要直接将系统敏感数据传入模板渲染的上下文字典,仅传入邮件需要用到的变量
内容的提问来源于stack exchange,提问作者giaggi
相关产品推荐
相关产品推荐

