ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Odoo 16从零实战:环境搭建与模块开发完整指南

Odoo 16从零实战:环境搭建与模块开发完整指南 简介Odoo 16按部就班实战精解基础篇是一套面向ERP初学者和Odoo二次开发者的视频源码配套资源覆盖从基础安装、模块创建到业务配置的完整路径帮助读者在缺少现场指导时也能按步骤完成Odoo 16环境搭建与功能定制。资源共包含554个文件以233个py后端逻辑源码、202个xml视图与菜单定义、43个mp4分阶段操作录屏为主辅以38个csv权限表和37张png界面截图整包约461.73MB视频与源码按阶段一一对应便于边看边练。实战内容聚焦Odoo 16新增的库存预测与保留释放、供应商发票自动匹配、销售流程优化、集团集采SRM以及生产制造补货策略等企业高频场景每个模块都给出可直接运行的Python模型和视图配置可对接真实业务需求进行二次开发。目前已有253人学习下载无论作为系统学习Odoo的基础教程还是快速了解新功能特性的参考手册都能显著降低上手门槛。1. Odoo 16 实战不要跳步按部就班的前提是把环境当成系统来建把 Odoo 16 从零跑起来这件事我见过不少开发者在同一条路上卡住照着网上的片段装到一半前端样式丢失、模块列表为空、视图报字段找不到最后只能删掉虚拟机重来。Odoo 16 是本地化部署场景里最常用的一代长期支持版本真正难的不是点击鼠标配业务而是环境、配置、模块骨架和数据视图这四个环节必须按顺序打通。这篇笔记就把这条链路拆成可复现的步骤装在哪、怎么起、最小模块怎么写、常见坑在哪、调试怎么验证。适合第一次接手 Odoo 16 的企业 IT 和独立开发者目标是让你照着做一次跑通而不是把时间耗在排错上。2. 装在哪、怎么选Odoo 16 需要的最小环境2.1 版本选型为什么基础篇只谈 Odoo 16Odoo 16 属于长期支持版本社区资料和第三方模块积累都相对完整配置语法和视图结构与 17、18 没有本质差异但网上能搜到的中文排错经验明显更多。对初学者来说追新版本不是不可以只是很多报错在刚发的前半年连官方 issue 里都还没有答案最后只能自己翻代码属于典型的“为了追新而翻车”。我看到很多团队最后停留在 Odoo 16 的真实原因不是不思进取而是业务模块跑在 16 上稳定二次开发改动的面可控。基础篇选 16 还有一个技术理由它的 Python 依赖在 3.8 到 3.10 之间兼容性最好部署环境选型余地大不会因为系统自带 Python 版本太新被迫升级一堆底层库。版本选型上我不建议一上来就研究 Docker 镜像的高可用方案。单机部署、源码方式跑通这是把 Odoo 16 吃透的第一课。Docker 能帮你省去环境安装但同时把配置目录、文件存储、进程管理变成黑匣子出了问题更难判断是容器问题还是 Odoo 本身的问题。先本地裸跑再把同一套配置迁移到容器是比较稳妥的路径。对比项Odoo 16新版本社区资料与中文文档多且稳定偏少英文为主Python 版本兼容3.8 – 3.10要求更高版本第三方模块覆盖绝大多数场景够用还在迁移中长期维护周期官方支持期长更依赖最新更新2.2 源码方式安装最小命令序列常见做法是在 Ubuntu 22.04 或 Debian 12 上装 Odoo 16因为系统自带 Python 版本合适PostgreSQL 安装也简单。我一般会创建一个独立系统用户来跑 Odoo而不是直接用 root一是避免文件权限混乱二是后续用 systemd 托管进程时更安全。下面的命令按顺序执行每一步都有依赖关系。# 更新系统包索引装编译和运行依赖 sudo apt update sudo apt install -y git python3 python3-pip python3-venv \ libpq-dev build-essential wget # 创建独立用户后面所有 Odoo 相关操作都在这个用户下执行 sudo useradd -m odoo16 # 从官方公开仓库克隆 16.0 分支--depth 1 只拉取当前快照 sudo -u odoo16 git clone --depth 1 --branch 16.0 \ https://github.com/odoo/odoo.git /home/odoo16/odoo # 创建 Python 虚拟环境隔离项目依赖 sudo -u odoo16 python3 -m venv /home/odoo16/venv # 安装 Odoo 的 Python 依赖requirements.txt 由官方维护 sudo -u odoo16 /home/odoo16/venv/bin/pip install -r \ /home/odoo16/odoo/requirements.txt克隆仓库时我特意加了--depth 1它只保留最新一次提交克隆体积小、速度快。后面需要升级版本时再git fetch --depth 1即可对基础篇完全够用。虚拟环境这一步很多人偷懒跳过直接拿系统 Python 跑结果装了一堆全局包后续项目一多就乱。venv 是 Python 开发的基本卫生习惯Odoo 16 也不例外。依赖安装完成后建议先跑一次版本检查确认环境没坏。命令是/home/odoo16/venv/bin/python /home/odoo16/odoo/odoo-bin --version能正常输出版本号就说明基础依赖没问题。如果报缺少某个模块不要急着手动 pip 安装先检查是不是 requirements.txt 没有全部装上这种报错多半是网络中断导致装到一半。2.3 数据库就绪PostgreSQL 用户与权限Odoo 默认使用当前操作系统的用户名去连接 PostgreSQL所以给系统用户 odoo16 同名的数据库用户是最省心的配置。开发环境可以给超级权限生产环境建议只给 createdb 权限否则 Odoo 初始化时无法建库。先安装 PostgreSQL再创建用户。sudo apt install -y postgresql # 创建与系统用户同名的数据库超级用户 sudo su - postgres -c createuser -s odoo16 # 验证能否以 odoo16 身份连接数据库服务 sudo -u odoo16 psql -l-s表示超级用户开发阶段省去很多权限排查的麻烦。如果生产环境不想给超级权限可以用这条命令替代sudo su - postgres -c createuser -o odoo16 --createdb只授予建库和创建角色权限。最终psql -l能列出数据库列表就说明连接成功。数据库这里最容易踩的坑是密码问题。Odoo 配置文件里如果不写db_password它默认用 Unix 本地连接的空密码方式访问 PostgreSQL这是正常配置不要手动填一个错误密码进去。如果你非要用密码连接必须在 PostgreSQL 里先给 odoo16 设置密码然后两边保持一致不能只在配置文件里改。提示本地开发的数据库操作都用 PostgreSQL 的 peer 认证Odoo 和数据库跑在同一台机器时配置里留空db_password是最稳的做法。3. 把配置文件写对Odoo 16 启动前必须懂的参数3.1 一份能跑的最小配置Odoo 16 的配置是 ini 格式默认情况下不写配置也能启动但那样会把数据库和数据目录放到奇怪的位置后期很难维护。我建议从第一次启动就固定配置文件路径我放在/etc/odoo16/odoo16.conf内容如下。这份配置是一个完整的最小集每行都有实际作用。[options] addons_path /home/odoo16/odoo/addons,/home/odoo16/my-addons data_dir /home/odoo16/odoo-data db_host 127.0.0.1 db_port 5432 db_user odoo16 db_password False dbfilter ^demo16$ web_interface 127.0.0.1addons_path是模块搜索路径多个目录用逗号分隔。第一段是官方自带模块目录第二段是自定义模块目录路径里必须写绝对路径。data_dir用来存放附件、会话和静态资源缓存我单独建了/home/odoo16/odoo-data目录避免和代码目录混在一起。db_host写成127.0.0.1而不是 localhost是为了让 Odoo 走 TCP 连接而不是 Unix socket配合db_password False时行为更稳定。dbfilter是数据库过滤正则^demo16$表示该实例只认 demo16 这一个数据库这个参数在生产环境特别重要能防止 Odoo 界面里看到并连上服务器上其他不相关的库。注意改了配置文件后必须重启 Odoo 进程才会生效。很多人改完配置刷新页面没用就以为是文件写错了。3.2 首次启动与数据库初始化配置文件就绪后第一次启动要完成数据库初始化。这个步骤会创建数据库结构并写入基础模块Odoo 16 中基础模块不是选的而是初始化时默认安装的。下面的命令执行完不会卡在后台它会初始化完自动退出方便看到所有日志输出。sudo -u odoo16 /home/odoo16/venv/bin/python \ /home/odoo16/odoo/odoo-bin \ -c /etc/odoo16/odoo16.conf \ -d demo16 \ --stop-after-init-d demo16指定要初始化的数据库名如果该数据库不存在会自动创建前提是配置里的 db_user 有建库权限。--stop-after-init是基础篇必须记住的参数它让 Odoo 完成初始化后立刻退出适合安装、升级模块时使用不会占住终端。等这条命令运行完再执行不带--stop-after-init的启动命令。如果一切正常日志末尾会显示 HTTP 服务在127.0.0.1:8069上监听浏览器访问这个地址就能看到页面。这里有个易错点很多人第一次启动直接用sudo -u odoo16跑后台服务其实基础篇阶段前台运行更好日志直接打在终端报错能立刻看到。3.3 前端资源起不来样式丢失与日志定位Odoo 16 的前端资源不是预编译好随代码分发的web 客户端首次启动时会做静态资源编译。最常见的问题是打开页面后完全没有样式控制台一堆资源加载失败。遇到这种情况先看启动日志再检查 data_dir 的权限。下面的命令把可能钩住的两个点都处理掉。# 创建数据目录并授权给 odoo16 用户 sudo mkdir -p /home/odoo16/odoo-data sudo chown -R odoo16:odoo16 /home/odoo16/odoo-data # 如果日志提示缺少 less 相关依赖重新完整安装依赖 sudo -u odoo16 /home/odoo16/venv/bin/pip install -r \ /home/odoo16/odoo/requirements.txt # 查看日志最后 50 行定位是权限还是资源加载问题 sudo -u odoo16 tail -n 50 /home/odoo16/odoo16.log启动 Odoo 时如果没指定--logfile日志会直接打在终端。第一次跑通后建议加一个参数把它落到文件里比如--logfile/home/odoo16/odoo16.log排错时不用一直挂着终端。样式丢失的另一个根源是浏览器缓存了旧的静态资源按 CtrlShiftR 强制刷新通常就能解决不必急着清数据目录。日志里如果看到lessc或者node相关报错说明前端编译环境缺少 node 组件回到 2.2 节确认系统级的npm有没有装。这类问题网上常有人建议清空 data_dir 重启但那属于最后手段清掉的是附件和会话数据不是代码数据一定要先确认日志内容再动手。4. 写第一个自定义模块Odoo 16 的最小可运行骨架4.1 模块目录与 manifest 骨架Odoo 16 的模块就是一个带固定结构的目录目录名是模块技术名称只能用小写字母和下划线。新建模块不需要命令行工具手动建目录就行结构如下。这个骨架是基础篇最核心的东西后面所有业务逻辑都是在这个基础上扩展出来的。my_first_module/ ├── __init__.py ├── __manifest__.py ├── models/ │ ├── __init__.py │ └── my_model.py └── views/ └── my_model_views.xml__manifest__.py是模块的声明文件告诉 Odoo 这个模块是谁、依赖什么、要加载哪些数据文件。下面的内容是所有 Odoo 16 模块的最小声明字段名一个都不能拼错否则安装直接报错。{ name: My First Module, version: 16.0.1.0.0, category: Tools, summary: 演示最小可运行模块, depends: [base], data: [ views/my_model_views.xml, ], installable: True, application: True, }depends列表必须包含 base这是 Odoo 所有模块的基础依赖。data里声明 XML 文件路径Odoo 安装模块时会按列表顺序加载这些文件。如果后续要加安全权限 CSV也要加到这里顺序是先加权限文件再加视图文件这个顺序是硬性要求。4.2 模型定义一个带名称和描述的表模型是 Odoo 里处理业务数据的核心每个模型对应数据库里的一张表。下面定义一个名为my.first.model的模型模型名用点分隔Odoo 会自动把它映射成数据库表my_first_model。先写模型文件再在models/__init__.py里导入。from odoo import models, fields class MyFirstModel(models.Model): _name my.first.model _description 我的第一个模型 name fields.Char(string名称, requiredTrue) description fields.Text(string备注) active fields.Boolean(string有效, defaultTrue)name字段不是必须的但 Odoo 的列表视图和搜索逻辑默认拿它做显示名所以基础模块里最好带上。active字段是 Odoo 的软删除机制值为 False 的记录在普通视图里默认不显示这个字段几乎是所有业务模型的标配。from . import my_modelmodels/__init__.py必须把新写的模型文件导入Python 的类才能被 Odoo 注册到模型系统里。很多新手改完my_model.py发现界面看不到新模型第一反应是代码写错了实际上八成是忘了在这里加导入。这两个文件写完后先做一次升级操作再进界面接下来 4.3 节会说视图这里先确认模型能建表。4.3 视图与菜单XML 数据文件的作用Odoo 16 的界面是用 XML 数据文件定义的菜单、动作、视图都是数据库里的记录。下面的 XML 定义一个窗口动作、一个顶级菜单和树状、表单两种视图。最外层标签是odoo里面每条record都是一条写入数据库的记录。odoo record idaction_my_first_model modelir.actions.act_window field namename我的模型/field field nameres_modelmy.first.model/field field nameview_modetree,form/field /record record idmenu_my_first_model modelir.ui.menu field namename我的模块/field field namesequence10/field field nameaction refaction_my_first_model/ /record record idview_my_first_model_tree modelir.ui.view field namenamemy.first.model.tree/field field namemodelmy.first.model/field field namearch typexml tree string我的模型 field namename/ field nameactive/ /tree /field /record record idview_my_first_model_form modelir.ui.view field namenamemy.first.model.form/field field namemodelmy.first.model/field field namearch typexml form string我的模型 sheet group field namename/ field namedescription/ field nameactive/ /group /sheet /form /field /record /odooview_mode里的tree,form表示列表视图优先、表单视图其次。上面这段 XML 里定义了自定义视图但窗口动作还没绑定它们所以实际打开的是 Odoo 自动生成的默认视图。要让自定义视图生效需要在动作里加view_ids配置基础篇阶段建议先不配等你看过自动视图长什么样再回来替换成自己的布局。这里需要解释一个容易误解的点独立定义一个视图记录并不会自动替换默认视图它只是多了一条视图配置。系统在渲染界面时会按model、type和优先级找到最合适的视图。想让列表页用自定义树状视图最简单的是等模块装好后在界面开发者模式里手动调整或者在本节代码基础上补全view_ids配置。基础篇先把记录建起来、理解record和field的对应关系就足够。4.4 安装与升级循环让改动生效的命令式写法模块写好后把它放到配置的addons_path里指定的自定义目录然后执行安装命令。Odoo 16 里安装和升级是两个不同的操作-i是安装-u是升级。下面的命令先把模块装进 demo16 数据库。sudo -u odoo16 /home/odoo16/venv/bin/python \ /home/odoo16/odoo/odoo-bin \ -c /etc/odoo16/odoo16.conf \ -d demo16 \ -i my_first_module \ --stop-after-init看到日志输出module my_first_module: installing就说明模块正在安装。此刻打开浏览器菜单应该能出现了但注意如果你还没配权限 CSV普通操作可能受限这是第 5 章要解决的问题。安装完成后后续每次修改 Python 模型或者 XML 视图都要执行升级而不是重装。sudo -u odoo16 /home/odoo16/venv/bin/python \ /home/odoo16/odoo/odoo-bin \ -c /etc/odoo16/odoo16.conf \ -d demo16 \ -u my_first_module \ --stop-after-initPython 模型字段改动后必须跑-u数据库列才会同步创建。XML 视图改动后同样跑-u视图记录才会被重新加载。如果改了代码不升级界面没有任何变化这是 Odoo 开发里最常见的血泪经验之一。我一般会养成习惯改完代码立刻升级看到日志末尾没有 ERROR 再切到界面验证。5. 避坑Odoo 16 基础实战里的五个高频报错5.1 安装模块后菜单没出现现象-i my_first_module执行成功日志没有报错但登录界面后整个侧边栏都找不到新菜单。原因最常见的是模型没有权限记录。Odoo 里新建模型后默认任何用户都没有读写权限界面里即使有菜单和动作点击后也会报权限错误或者干脆不显示。第二个常见原因是菜单记录没有配父级菜单顶栏里不会自动出现。解决在模块里加一个权限文件security/ir.model.access.csv然后把它加进 manifest 的data。这是唯一标准的解决办法。id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_my_first_model_all,my.first.model.all,model_my_first_model,,1,1,1,1model_id:id写model_my_first_model这是 Odoo 根据模型自动生成的外部标识。group_id:id留空表示所有人可用。加完文件后重新升级模块菜单才能正常使用。5.2 改了模型字段数据库没有新列现象在my_model.py里新增了一个字段升级模块后进入界面系统报字段不存在或者数据库查询出错。原因改完 Python 模型没有执行-u升级或者升级时数据库连接配置不对导致建列失败。Odoo 不会在你修改代码后自动同步数据库表结构它只在升级模块时对比模型定义和实际表结构。解决执行 4.4 节的升级命令。升级过程中日志会把每个模型的字段变更打出来如果没有看到你的新字段说明模块路径不对检查addons_path和模块目录名是否一致。注意有些开发者图省事直接重启服务不升级模块这样永远不会生效。在 Odoo 16 里改 Python 模型字段后重启服务 刷新页面是错误的调试路径。5.3 视图报错Field xxx not found现象升级模块时直接报错Field description does not exist或者类似的字段不存在错误模块无法完成安装。原因XML 视图里写了模型没有的字段名称或者模型类没有被正确导入Odoo 在加载视图时找不到对应的字段定义。解决先把 XML 里所有field标签的name属性和模型文件里的字段定义逐行对照。再看一眼models/__init__.py有没有把模型模块 import 进来。最后确认depends里包含 base如果视图里引用了其他模块的模型还要在 manifests 里加对应依赖。这个报错是新手最容易怕的类型其实排查路径非常固定字段名 → import → 依赖。5.4 addons_path 只写了一个路径自己模块永远不可见现象在浏览器应用列表里找不到my_first_module安装模块下拉列表为空或者只有系统自带模块。原因配置文件里的addons_path只写了官方模块目录/home/odoo16/odoo/addons自定义模块目录没有加入。Odoo 不会自动递归扫描其他位置的模块。解决确保配置里用逗号同时列出两个路径并重启服务。这是修改配置文件后必须做的一步重启 Odoo 进程重新读取配置再进应用列表搜索模块。addons_path /home/odoo16/odoo/addons,/home/odoo16/my-addons这里有个排查技巧启动 Odoo 时加--log-leveldebug日志里会输出所有已加载模块的列表。如果自定义目录下的模块没出现检查模块目录下有没有__manifest__.py以及该文件是否能被 Python 正常解析json格式错误会导致整个模块被静默跳过。5.5 前端资源错乱没有样式部分按钮不断加载现象页面能打开但完全没有 CSS 样式列表页和表单页布局混乱一些按钮点击后一直转圈没有响应。原因data_dir 里的静态资源缓存损坏或不完整或者数据目录权限不足Odoo 无法正常生成前端资源。这类问题在反复重启、物理机断电后较容易出现。解决第一步确认 data_dir 归属用户是 odoo16。第二步清理残旧资源这是基础篇阶段最直接的方法只在开发环境做生产环境要谨慎清数据。sudo -u odoo16 rm -rf /home/odoo16/odoo-data/filestore sudo -u odoo16 rm -rf /home/odoo16/odoo-data/sessions清理后重启 Odoo让它重新生成全部静态资源。如果你部署的实例已经跑了一段时间里面可能有上传附件清掉 filestore 会丢失这些文件所以这个操作只适合本地开发库。先排查日志和权限不要一上来就清数据目录这样容易把没有问题的附件也一起误删。6. 用调试与数据复位把 Odoo 16 开发节奏拉起来6.1 日志内联与 debug 模式基础篇后期你应该把启动命令固定成带日志文件的写法日志是 Odoo 16 排错的第一信息来源。下面这条命令会输出比默认更详细的日志包括 SQL 查询和视图加载过程遇到权限和字段问题时比猜代码高效得多。sudo -u odoo16 /home/odoo16/venv/bin/python \ /home/odoo16/odoo/odoo-bin \ -c /etc/odoo16/odoo16.conf \ -d demo16 \ --logfile/home/odoo16/odoo16.log \ --log-leveldebug--log-leveldebug会输出大量细节生产环境不建议开本地开发时开起来能让很多隐蔽问题现形。浏览器端还有一个技巧把登录地址换成http://127.0.0.1:8069/web?debug1页面右上角会多出调试菜单可以直接查看视图层级和模型字段特别适合对照 XML 检查界面结构。6.2 用测试文件验证字段约束基础篇的模块还没有复杂逻辑但可以把验证方式提前养成测试习惯。在模块下建tests/__init__.py和tests/test_my_model.py写一个最小测试用例检查模型创建和必填字段约束。from odoo.tests import Common class TestMyModel(Common): def test_name_create(self): rec self.env[my.first.model].create({name: demo}) self.assertEqual(rec.name, demo)运行测试用下面的命令--test-tags指定模块名只跑当前模块的测试不会把整个库的测试全部跑一遍。sudo -u odoo16 /home/odoo16/venv/bin/python \ /home/odoo16/odoo/odoo-bin \ -c /etc/odoo16/odoo16.conf \ -d demo16 \ --test-enable \ --test-tags my_first_module \ --stop-after-init输出里出现Tests: 1就说明测试生效了。我自己的经验是测试不一定要覆盖所有逻辑但至少把创建、读取、字段约束这类基础路径守住。这样每次改完模型跑一次测试比反复手工点界面确认要踏实得多。6.3 数据复位删库重建而不是清数据库开发和调试到后期demo16 库里会堆积大量实验数据继续在这个库里升级模块可能产生各种奇怪残留。最干净的复位方法是直接把数据库删掉重建再初始化一次。这个习惯能避免很多玄学问题库是全新结构所有模块都是重新安装状态可控。sudo -u postgres dropdb demo16 sudo -u postgres createdb demo16 -O odoo16重建后执行第 3 章的初始化命令然后重新安装模块。整个过程一分钟不到换来的是一个完全干净的验证环境。我早期在同一个库里反复升级遇到字段残留问题经常要翻旧账后来改成“先 dropdb 再重来”反而省下大量时间。Odoo 16 基础阶段的代码量不大删库重建没有任何心理负担等真正进入业务数据阶段再来考虑数据库迁移和备份方案。希望这篇笔记能帮你把 Odoo 16 的入门路径走成一条明确可复现的链路不靠运气跑通也不在排错上反复徘徊。本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表