Odoo12自定义弹窗实现与优化实践
1. 项目背景与需求分析在Odoo12开发过程中系统默认的消息提示机制存在几个明显痛点。最常见的就是使用raise抛出UserError或Warning异常时会显示Odoo Server Error这样的系统错误标题不仅视觉上不专业更重要的是在Dialog弹窗场景下会导致表单数据丢失。这种体验对终端用户极不友好。我在实际项目中就遇到过这样的案例财务人员在审核付款单时系统提示供应商银行信息不完整但由于使用了传统的异常抛出方式导致已填写的20多个字段数据全部清空。这种设计缺陷直接影响了业务流程效率。2. 技术方案设计思路2.1 传统方案的局限性Odoo原生提供的消息提示方式主要有raise UserError(message)raise Warning(message)return { warning: {title: 提示, message: 内容} }这些方式共同的缺点是样式不可定制始终带有错误警示标识弹窗关闭后无法执行回调函数在复杂表单中可能引发数据丢失2.2 自定义弹窗的优势我们采用TransientModel临时模型 自定义视图的方案可以实现完全可控的UI样式支持自定义按钮和回调事件保持主表单数据不丢失可扩展的交互逻辑3. 完整实现步骤3.1 创建消息向导模型在models目录下新建my_message_wizard.pyfrom odoo import models, fields, api class MyMessageWizard(models.TransientModel): _name my.message.wizard _description 自定义消息弹窗 message fields.Text( string消息内容, requiredTrue, readonlyTrue ) api.multi def action_confirm(self): 确认按钮回调方法 return {type: ir.actions.act_window_close}关键点说明必须继承TransientModel而非Model字段设置为readonly防止误修改返回标准窗口关闭动作3.2 设计弹窗视图在views目录创建my_message_wizard.xmlodoo record idmy_message_wizard_form modelir.ui.view field namenamemessage.wizard.form/field field namemodelmy.message.wizard/field field namearch typexml form string系统提示 sheet div classoe_title h1i classfa fa-info-circle/ 重要提示/h1 /div group field namemessage classoe_inline widgethtml/ /group /sheet footer button nameaction_confirm string确认 typeobject classbtn-primary default_focus1/ /footer /form /field /record /odoo视图设计技巧使用sheet和group规范布局添加Font Awesome图标增强视觉效果采用html widget支持富文本内容设置default_focus让按钮自动获得焦点3.3 注册模块资源在__manifest__.py中添加data: [ views/my_message_wizard.xml, ],3.4 业务逻辑调用示例在需要提示的地方调用def button_validate(self): if not self.partner_id: message self.env[my.message.wizard].create({ message: p请先选择业务伙伴/p ul li该提示不会中断业务流程/li li表单数据将保持原状/li /ul }) return { name: 缺失必填项, type: ir.actions.act_window, view_mode: form, res_model: my.message.wizard, res_id: message.id, target: new, context: self._context, flags: {mode: readonly} } # 正常业务逻辑...4. 高级功能扩展4.1 多按钮交互改造action_confirm方法def action_choice(self, choice): if choice confirm: self.env[res.partner].search([...]).do_something() return {type: ir.actions.act_window_close} # 视图添加 button nameaction_choice string同意 typeobject args(confirm,)/ button nameaction_choice string拒绝 typeobject args(reject,)/4.2 自动关闭定时器在js文件中添加setTimeout(function() { $(.modal).modal(hide); }, 5000); // 5秒后自动关闭4.3 响应式布局适配添加CSS类sheet classmsg-responsive style .msg-responsive { min-width: 300px; max-width: 80%; margin: 0 auto; } media (max-width: 768px) { .msg-responsive { max-width: 95%; } } /style ... /sheet5. 常见问题排查5.1 弹窗不显示检查步骤确认__manifest__.py已注册XML文件检查视图record id是否唯一查看浏览器控制台是否有JS错误5.2 按钮无响应调试方法在方法开始添加_logger.debug调试输出检查是否缺少api.multi装饰器确认按钮typeobject而非typeaction5.3 样式异常解决方案检查是否与其他模块CSS冲突确保正确加载了Font Awesome使用浏览器开发者工具审查元素6. 性能优化建议对频繁调用的提示内容使用缓存tools.ormcache(message_content) def get_message_id(self, message_content): return self.create({message: message_content}).id批量处理时避免N1查询# 错误做法 for record in records: record.show_message(...) # 正确做法 message_ids self.env[my.message.wizard].create_batch([...])使用web_ajax代替完整弹窗odoo.define(module, function (require) { use strict; var core require(web.core); var Widget require(web.Widget); var MyWidget Widget.extend({ showToast: function(message) { this.do_notify(_t(提示), message); } }); });我在实际项目中发现当需要连续显示多个提示时采用通知(toast)样式比模态弹窗更合适。特别是在导出入库单这类批量操作场景下可以显著改善用户体验。

相关新闻

C语言编程入门:从基础概念到开发环境配置

C语言编程入门:从基础概念到开发环境配置

1. C语言编程预备知识概述第一次接触C语言时,很多人会被各种概念和术语搞得晕头转向。作为一个从1998年就开始写C的老程序员,我想用最直白的方式帮你理清这些基础知识。C语言之所以被称为"编程界的拉丁语",不仅因为它的历史悠久&am…

2026/10/13 2:36:40 阅读更多 →
Java环境配置与JDK安装全指南

Java环境配置与JDK安装全指南

1. Java环境配置基础概念Java环境配置是每个Java开发者必须掌握的基础技能。简单来说,它就是在你的操作系统上设置好Java开发所需的工具和路径,让系统能够识别和执行Java命令。这就像给电脑安装一个"翻译官",让它能听懂并执行Java语…

2026/10/12 23:18:54 阅读更多 →
Android开源项目全流程打造与专业徽章配置指南

Android开源项目全流程打造与专业徽章配置指南

1. Android开源项目全流程打造指南 作为一个长期活跃在GitHub社区的Android开发者,我经常被问到一个问题:"如何让自己的开源项目看起来更专业?"今天我就来分享一套完整的Android开源项目打造方案,从项目创建到各种专业…

2026/10/12 12:13:25 阅读更多 →

最新新闻

商人过河问题详解:状态转移与BFS的Matlab实现

商人过河问题详解:状态转移与BFS的Matlab实现

1. 从一道经典建模题说起:商人过河到底在考什么数学建模入门阶段,几乎人人都会碰到“商人过河”这道题。题目本身并不复杂:三个商人带着三个随从,要坐一条小船过河,小船每次最多载两人,而且无论在哪一岸&am…

2026/10/13 2:36:32 阅读更多 →
机器学习加速超材料逆向设计:从电磁仿真到参数搜索的实战指南

机器学习加速超材料逆向设计:从电磁仿真到参数搜索的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 2:36:32 阅读更多 →
DeepSeek Harness插件:笔记整理与会话管理实战指南

DeepSeek Harness插件:笔记整理与会话管理实战指南

这次我们来看一个跑得很快的 AI 工具项目:围绕 DeepSeek 模型能力做的两款 Harness 插件,一款负责笔记整理,一款负责会话管理。项目上线不到一周,GitHub 接近 4000 个 star,在插件类项目里算很扎眼的起步速度。从这个热…

2026/10/13 2:36:32 阅读更多 →
Trae 技能配置实战:用 skills.md 让 AI 编程不再自由发挥

Trae 技能配置实战:用 skills.md 让 AI 编程不再自由发挥

你是不是也有这种体验:用 AI IDE 写代码,对话窗里聊得头头是道,真让它干活又开始自由发挥,步骤乱、输出格式乱,结果照样要自己返工。问题根源很多时候不是模型不够聪明,而是缺少一份标准操作说明书。skills…

2026/10/13 2:36:32 阅读更多 →
501B开放权重稠密大模型:部署、量化与蒸馏实操指南

501B开放权重稠密大模型:部署、量化与蒸馏实操指南

1. 从“501B 开放权重”这个数字说起第一次看到“501B 参数、开放权重”这两个词摆在一起,我的第一反应不是兴奋,而是算账。501B 这个量级,按常见的 FP16 精度算,光权重就要占掉大约 1TB 的显存空间;就算上 INT8 量化&…

2026/10/13 2:36:32 阅读更多 →
Trae实测:从对话生成到Agent执行,AI编程工具如何改变开发流程

Trae实测:从对话生成到Agent执行,AI编程工具如何改变开发流程

最近AI Coding已经热到不需要再解释背景了。从最早的代码补全,到能直接对话生成整段功能,再到现在的Agent式“你提需求、它动手改代码”,这一波工具迭代的速度,确实让很多开发者的日常工作方式都变了。我陆陆续续试过不少同类产品…

2026/10/13 2:35:32 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →