当前位置: 首页 > news >正文

第23讲、Odoo18 邮件系统整体架构

目录

  1. Odoo 邮件系统整体架构
  2. 邮件发送方式
  3. 邮件模板配置
  4. SMTP 邮件服务器配置
  5. 邮件发送过程
  6. 开发中常见邮件发送需求
  7. 常见问题排查
  8. 提示与最佳实践
  9. 完整示例:审批通过自动发邮件
  10. 门户表单自动邮件通知案例
  11. 邮件队列与异步发送
  12. 邮件添加附件
  13. 邮件日志与调试
  14. 多语言邮件模板
  15. 邮件安全与反垃圾建议
  16. 常见报错案例
  17. 参考链接

Odoo 18 的邮件系统基于强大的邮件引擎,广泛应用于用户通知、自动化邮件、营销推广、模板化邮件及附件发送等多种场景。本文将从系统架构、发送方式、配置方法、开发实践等多个维度,系统梳理 Odoo 邮件功能的原理与实战技巧,助你高效掌握企业级邮件自动化。


🧱 一、Odoo 邮件系统整体架构

Odoo 的邮件系统围绕以下核心模型构建:

模型说明
mail.mail单条待发送邮件记录(每封邮件生成一条)
mail.message邮件消息记录(通知、聊天、讨论、评论等)
mail.template邮件模板,支持变量替换
ir.mail_serverSMTP 邮件服务器配置
res.partner接收者(通常为联系人)
mail.thread支持消息、跟踪和通知的模型继承类

🛠️ 二、邮件发送方式

Odoo 支持多种邮件发送方式,满足不同业务需求:

1. 使用 mail.template 模板发送(推荐,适合业务通知)

适用于大多数业务场景,支持变量替换和批量发送。

# 通过模板发送邮件,force_send=True 表示立即发送,否则进入队列
template = self.env.ref('your_module.email_template_project_approval')
template.send_mail(record_id, force_send=True)

2. 使用 mail.mail 模型手动构建邮件

适合自定义内容、附件等特殊场景。

mail = self.env['mail.mail'].create({'subject': '通知标题','body_html': '<p>这是一封自动邮件</p>','email_to': 'abc@example.com','email_from': 'no-reply@yourcompany.com',
})
mail.send()

3. 使用 record.message_post() 发送内部通知

适合在模型记录上快速发送系统消息或评论。

record.message_post(body="您的申请已审批通过。",subject="审批通过通知",message_type='notification',subtype_xmlid='mail.mt_comment',partner_ids=[user.partner_id.id],
)

⚙️ 三、邮件模板配置(mail.template)

邮件模板支持灵活的变量替换和 HTML 格式,便于统一管理邮件内容。

字段示例说明
Subject项目 ${object.name} 已通过支持 Jinja 表达式
Body HTML<p>尊敬的 ${object.partner_id.name}...</p>支持 HTML
Modelproject.project指定模型
Email To${object.user_id.email}收件人

XML 示例:

<record id="email_template_project_approval" model="mail.template"><field name="name">Project Approved</field><field name="model_id" ref="project.model_project_project"/><field name="subject">项目 ${object.name} 审批通过</field><field name="email_to">${object.user_id.email}</field><field name="body_html"><![CDATA[<p>您好,${object.user_id.name}:</p><p>您的项目申请 <strong>${object.name}</strong> 已通过审批。</p>]]></field>
</record>

📡 四、SMTP 邮件服务器配置

路径:设置 > 技术 > 邮件 > 外发邮件服务器

字段示例
SMTP 服务器smtp.gmail.com
端口587
使用 TLS
登录名you@example.com
密码yourpassword

配置完成后可测试邮件发送是否正常。


🧪 五、邮件发送过程(背后流程)

  1. mail.template.send_mail() 创建 mail.mail 记录
  2. mail.mail.send() 通过 SMTP 发出邮件
  3. 发送成功状态为 sent,失败为 exception
  4. 可通过计划任务定期处理 mail.mail 队列

📌 六、开发中常见邮件发送需求

场景:审批通过后自动发送通知邮件

def action_approve(self):self.state = 'approved'template = self.env.ref('your_module.email_template_project_approval')template.send_mail(self.id, force_send=True)

🧩 七、常见问题排查

问题解决方案
邮件发不出检查 SMTP 设置、日志、是否有未发 mail.mail
收件人收不到检查 email_to、SMTP 服务器是否被拒发
模板变量渲染失败检查模型/字段拼写,建议开发模式调试
HTML 内容乱码使用 CDATA 标签包裹 HTML

📌 八、提示与最佳实践

  • 优先使用 mail.template 统一管理邮件格式
  • 可用 email_ccemail_bcc 设置抄送
  • 立即发送用 force_send=True
  • 大量邮件建议用队列机制异步处理

📄 九、完整示例:审批通过自动发邮件

以下为审批通过后自动发送邮件的完整流程,包括模板、模型方法和控制器:

1. 邮件模板 XML(data/email_template.xml

<odoo><data><record id="email_template_project_approved" model="mail.template"><field name="name">Project Approval Notification</field><field name="model_id" ref="your_module.model_project_project"/><field name="subject">[Odoo] Project "${object.name}" Approved</field><field name="email_to">${object.user_id.email or ''}</field><field name="email_from">${(user.email or 'admin@example.com')}</field><field name="body_html" type="html"><![CDATA[<p>Dear ${object.user_id.name},</p><p>Your project <strong>${object.name}</strong> has been <strong>approved</strong>.</p><p>Thank you,<br/>The Management Team</p>]]></field></record></data>
</odoo>

2. 模型方法发送邮件(models/project.py

from odoo import models, fields, apiclass ProjectProject(models.Model):_name = 'project.project'_inherit = ['mail.thread']  # 支持消息通知name = fields.Char(string='Project Name')user_id = fields.Many2one('res.users', string='Responsible')state = fields.Selection([('draft', 'Draft'),('approved', 'Approved'),], default='draft')def action_approve(self):for rec in self:rec.state = 'approved'# 发送邮件template = self.env.ref('your_module.email_template_project_approved')if template:template.send_mail(rec.id, force_send=True)# 记录系统消息rec.message_post(body="项目已审批通过,通知已发送。")

3. 控制器触发发送(controllers/main.py

from odoo import http
from odoo.http import requestclass ProjectController(http.Controller):@http.route('/project/approve/<int:project_id>', type='http', auth='user', website=True)def approve_project(self, project_id):project = request.env['project.project'].sudo().browse(project_id)if project.exists():project.action_approve()return request.render('your_module.project_approval_success', {'project': project})else:return request.not_found()

你可以在浏览器访问 /project/approve/1 来审批 ID 为 1 的项目,并发送邮件。


🧪 十、测试步骤

  1. 在自定义模块中添加上述 XML、Python 和控制器代码
  2. 安装模块并确保 SMTP 设置正确
  3. 创建项目记录(填写 nameuser_id
  4. 浏览器访问 /project/approve/1
  5. 检查收件人邮箱是否收到邮件

💡 十一、门户表单自动邮件通知案例

适用于 Odoo 14~18,常见于"项目申请"、“需求提交”、"报名"等门户场景。

1. 场景描述

用户(如客户、员工)在门户网站提交"项目申请表单"后:

  1. 项目记录保存进 project.project 模型
  2. 自动通知相关负责人(如管理员)
  3. 返回提交成功页面

2. 模型定义(models/project.py

from odoo import models, fieldsclass ProjectProject(models.Model):_name = 'project.project'_description = 'Project Application'_inherit = ['mail.thread']name = fields.Char("Project Name", required=True)description = fields.Text("Description")applicant_email = fields.Char("Applicant Email")state = fields.Selection([('draft', 'Draft'),('submitted', 'Submitted'),], default='draft')

3. 邮件模板(data/email_template.xml

<odoo><data><record id="email_template_project_submit_notice" model="mail.template"><field name="name">New Project Application</field><field name="model_id" ref="your_module.model_project_project"/><field name="subject">[Odoo] New Project Application: ${object.name}</field><field name="email_to">admin@example.com</field> <!-- 可用对象字段替换 --><field name="body_html" type="html"><![CDATA[<p>Dear Admin,</p><p>A new project has been submitted:</p><ul><li><strong>Name:</strong> ${object.name}</li><li><strong>Email:</strong> ${object.applicant_email}</li><li><strong>Description:</strong> ${object.description}</li></ul>]]></field></record></data>
</odoo>

4. 控制器 + 表单页面(controllers/main.py

from odoo import http
from odoo.http import requestclass ProjectFormController(http.Controller):@http.route('/project/apply', type='http', auth='public', website=True)def show_form(self, **kwargs):return request.render('your_module.project_form_template')@http.route('/project/apply/submit', type='http', auth='public', website=True, csrf=False)def submit_form(self, **post):project = request.env['project.project'].sudo().create({'name': post.get('name'),'description': post.get('description'),'applicant_email': post.get('email'),'state': 'submitted',})# 发送邮件通知template = request.env.ref('your_module.email_template_project_submit_notice')if template:template.sudo().send_mail(project.id, force_send=True)return request.render('your_module.project_form_thankyou', {'project': project})

5. 前端模板 QWeb(views/portal_form_templates.xml

<template id="project_form_template" name="Project Apply Form"><t t-call="website.layout"><div class="container mt-5"><h2>Project Application</h2><form action="/project/apply/submit" method="post"><div class="form-group"><label>Project Name</label><input type="text" name="name" class="form-control" required="required"/></div><div class="form-group"><label>Email</label><input type="email" name="email" class="form-control" required="required"/></div><div class="form-group"><label>Description</label><textarea name="description" class="form-control" rows="4"></textarea></div><button type="submit" class="btn btn-primary mt-3">Submit</button></form></div></t>
</template><template id="project_form_thankyou" name="Thank You Page"><t t-call="website.layout"><div class="container mt-5"><h2>Thank You!</h2><p>Your project "<t t-esc="project.name"/>" has been submitted successfully.</p></div></t>
</template>

6. 模块加载配置(__manifest__.py

确保加载视图、模板、邮件模板:

'data': ['data/email_template.xml','views/portal_form_templates.xml',
],

7. 测试流程

  1. 浏览器访问:http://yourdomain.com/project/apply
  2. 填写并提交表单
  3. 邮件自动发送到设置的收件人邮箱(如 admin@example.com
  4. 页面跳转到感谢页

8. 可选扩展

  • 使用 res.users 查找管理员动态收件人
  • 设置 email_from 为申请人邮箱(如 ${object.applicant_email}
  • 后端审批后自动通知申请人

🕒 十二、邮件队列与异步发送

Odoo 默认通过队列机制异步发送邮件,适合大批量场景。可在"设置 > 技术 > 自动化 > 计划任务"找到 Email Queue Manager,定时处理 mail.mail 队列。

如需手动触发队列发送,可在 Odoo shell 执行:

self.env['mail.mail'].process_email_queue()

大批量发送建议不要用 force_send=True,避免阻塞事务。


📎 十三、邮件添加附件

发送邮件时可通过 attachment_ids 字段添加附件:

attachment = self.env['ir.attachment'].create({'name': 'example.pdf','datas': base64.b64encode(b'file content'),'type': 'binary','mimetype': 'application/pdf',
})
mail = self.env['mail.mail'].create({'subject': '带附件的邮件','body_html': '<p>请查收附件</p>','email_to': 'abc@example.com','attachment_ids': [(4, attachment.id)],
})
mail.send()

📝 十四、邮件日志与调试

  • 所有邮件发送记录可在"设置 > 技术 > 邮件 > 外发邮件"查看
  • 邮件失败时可在"外发邮件"列表中查看异常原因
  • 开发调试时可在 Odoo 日志中搜索 mail.mail 相关日志,定位问题

🌏 十五、多语言邮件模板

Odoo 支持多语言邮件模板。可在模板表单页切换语言,分别填写不同语言内容。发送时会自动根据收件人语言选择模板内容。


🔒 十六、邮件安全与反垃圾建议

  • 建议配置 SPF、DKIM、DMARC 提升送达率,防止被判为垃圾邮件
  • 邮件内容避免敏感词或大量外链
  • email_from 建议用已验证域名邮箱

❓ 十七、常见报错案例

  • SMTPAuthenticationError:检查邮箱账号和密码,部分邮箱需开启"应用专用密码"
  • ConnectionRefusedError:检查 SMTP 服务器地址和端口,服务器是否允许外部连接
  • 模板变量渲染失败:确认字段拼写、模型是否正确,建议开发者模式调试

🔗 参考链接

  • Odoo 官方文档 - 邮件
  • Odoo 邮件模板开发指南

结语




Odoo 邮件系统功能强大且灵活,既能满足日常通知,也能支撑复杂的业务自动化。建议开发者优先使用模板统一管理邮件格式,合理利用队列机制提升性能,并关注邮件日志与异常处理,保障邮件送达率。欢迎在评论区留言交流更多实战经验!

相关文章:

  • nonlocal 与global关键字
  • AIGC的产品设计演进:从工具到协作者
  • 实战:子组件获取父组件订单信息
  • AI联网时代嵌入式不再闭门造车--嵌入式开发工具软件针对性断网隔离方法原理与实测
  • Rest-Assured API 测试:基于 Java 和 TestNG 的接口自动化测试
  • golang常用库之-go-i18n库(国际化)
  • STM32学习之I2C(理论篇)
  • 智慧零售管理中的客流统计与属性分析
  • tableau 实战工作场景常用函数与LOD表达式的应用详解
  • rl_sar实现sim2real的整体思路
  • 按字典序排列最小的等效字符串
  • 第三章支线二 ·函数幻阶:语法召唤与逻辑封印
  • C#提取CAN ASC文件时间戳:实现与性能优化
  • < 自用文 OS有关 新的JD云主机> 国内 京东云主机 2C4G 60G 5Mb 498/36月 Ubuntu22
  • 618来了,推荐京东云服务器
  • 如何构建船舵舵角和船的航向之间的动力学方程?它是一个一阶惯性环节吗?
  • python打卡第47天
  • ArcPy扩展模块的使用
  • 数控滑台技术革新:实现高效精密加工的全面探索
  • 【读论文】U-Net: Convolutional Networks for Biomedical Image Segmentation 卷积神经网络
  • 东莞营销商城网站建设/开发app需要多少资金
  • 网站建设cms系统/推广平台下载
  • 郑州网站建设最独特/seo关键词排名优化费用
  • 在线制作海报网站/网络推广法
  • 英涛祛斑 网站开发/上海百度
  • 网站建设电话推广话术/合肥seo代理商