第3讲、Odoo 18 Base模块源码与ir.http机制深度解析
1. Odoo 18 base 模块结构总览
下表为 base 模块主要目录与文件说明:
| 目录/文件 | 说明 |
|---|---|
__manifest__.py |
模块描述信息,定义依赖、数据加载、初始化行为等 |
__init__.py |
模块初始化入口,导入 models、controllers 等 |
models/ |
所有 Python 模型定义,核心 ORM 功能在此实现 |
views/ |
QWeb、Form、Tree、Action、Menu 等 XML 视图配置 |
security/ |
权限规则(ir.model.access.csv)和记录规则(ir.rule)定义 |
data/ |
系统初始数据、公司数据、货币、语言等加载 |
wizard/ |
向导类功能,如更改密码、初始化公司信息 |
report/ |
报表模板与配置 |
controllers/ |
HTTP 控制器,如登录接口、Web 客户管理等 |
static/ |
静态资源(图标、样式) |
i18n/ |
多语言翻译文件 |
rng/ |
XML schema 验证文件 |
tests/ |
单元测试与回归测试脚本 |
2. 重点模块与模型详解
2.1 基础模型
-
res.users(用户)- 作用:系统用户表,管理后台登录账号、权限、用户偏好等。
- 关键字段:
login(用户名)、password(密码)、groups_id(所属权限组)、partner_id(关联联系人)、active(是否激活)。 - 典型用法:权限分配、用户管理、审计追踪。
- 案例:创建新用户并分配权限组
# 在 Odoo 18 的 shell 或自定义模块中 new_user = env['res.users'].create({ 'name': '新员工', 'login': 'newuser', 'password': 'securepassword', 'groups_id': [(6, 0, [env.ref('base.group_user').id])], # 分配"内部用户"组 'partner_id': env['res.partner'].create({'name': '新员工'}).id, })
-
res.groups(权限组)- 作用:权限分组,控制菜单、字段、操作的可见性和可用性。
- 关键字段:
name、category_id、users。 - 典型用法:角色管理、功能授权。
- 案例:为权限组分配菜单访问权限(XML)
<record id="group_sales_manager" model="res.groups"> <field name="name">销售经理</field> <field name="category_id" ref="base.module_category_sales_management"/> </record> <menuitem id="menu_sales" name="销售" groups="group_sales_manager"/>
-
res.partner(联系人/公司)- 作用:统一管理客户、供应商、员工、公司等一切"联系人"。
- 关键字段:
name、email、phone、company_type。 - 典型用法:客户关系、供应链、员工档案。
- 案例:创建联系人并指定为公司
partner = env['res.partner'].create({ 'name': '某科技有限公司', 'company_type': 'company', 'email': 'info@company.com', })
-
res.company(公司)- 作用:多公司支持,隔离数据、配置。
- 关键字段:
name、currency_id、partner_id。 - 典型用法:多公司账套、权限隔离。
- 案例:新建公司并指定默认货币
company = env['res.company'].create({ 'name': '分公司A', 'currency_id': env.ref('base.USD').id, })
-
res.lang(语言)- 作用:多语言支持,定义系统可用语言及格式。
- 关键字段:
code、name、date_format。 - 典型用法:本地化、国际化。
- 案例:激活新语言
lang = env['res.lang'].search([('code', '=', 'ja_JP')]) if lang: lang.active = True
-
res.currency(货币)- 作用:多币种支持,管理汇率、符号等。
- 关键字段:
name、symbol、rate。 - 典型用法:财务、销售、采购多币种结算。
- 案例:更新货币汇率
usd = env.ref('base.USD') usd.rate = 7.2
2.2 模型注册系统
-
ir.model(模型注册表)- 作用:注册所有 ORM 模型,支持动态扩展、元数据管理。
- 关键字段:
model(模型技术名)、name(显示名)、state。 - 典型用法:开发自定义模型、元编程、自动生成界面。
- 案例:查询所有已注册模型
models = env['ir.model'].search([]) for m in models: print(m.model, m.name)
-
ir.model.fields(字段注册表)- 作用:注册每个模型的字段,支持动态字段、字段权限。
- 关键字段:
name、model_id、ttype(字段类型)、required。 - 典型用法:动态表单、字段扩展、权限控制。
- 案例:查询模型的所有字段
fields = env['ir.model.fields'].search([('model', '=', 'res.partner')]) for f in fields: print(f.name, f.ttype)
2.3 权限机制
-
ir.model.access(访问控制表)- 作用:定义模型的增删改查权限,按组分配。
- 关键字段:
name、model_id、group_id、perm_read、perm_write。 - 典型用法:细粒度权限、合规审计。
- 案例:为模型添加访问控制规则(CSV)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_partner_user,res.partner user,model_res_partner,base.group_user,1,0,0,0
-
ir.rule(记录规则)- 作用:基于 domain 的数据行级权限控制。
- 关键字段:
name、model_id、domain_force、groups。 - 典型用法:多公司、部门隔离、审批流。
- 案例:为模型添加记录规则(XML)
<record id="rule_partner_company" model="ir.rule"> <field name="name">本公司联系人可见</field> <field name="model_id" ref="base.model_res_partner"/> <field name="domain_force">[("company_id", "=", user.company_id.id)]</field> <field name="groups" eval="[(4, ref('base.group_user'))]"/> </record>
-
权限校验链条:Odoo 的权限校验分为模型级和记录级,确保数据安全。机制为先查
ir.model.access,再查ir.rule,最后结合res.groups判定最终权限。- 案例:用户访问数据时的权限校验链(伪代码)
# Odoo 框架自动完成,无需手动调用 records = env['res.partner'].search([]) # 自动应用访问控制和记录规则
- 案例:用户访问数据时的权限校验链(伪代码)
2.4 数据导入导出与持久化标识
-
ir.model.data(数据唯一标识)- 作用:为所有持久化数据(如菜单、视图、动作等)分配唯一 XML ID,支持升级、导入导出。
- 关键字段:
module、name、model、res_id。 - 典型用法:模块升级、数据迁移、外部集成。
- 案例:通过 XML ID 获取数据
partner = env.ref('base.main_partner')
-
ir.exports(导出模板)- 作用:保存用户自定义的数据导出字段模板。
- 关键字段:
name、export_fields。 - 典型用法:批量导出、定制报表。
- 案例:保存自定义导出模板
export = env['ir.exports'].create({ 'name': '导出联系人', 'resource': 'res.partner', 'export_fields': [(0, 0, {'name': 'name'}), (0, 0, {'name': 'email'})], })
-
ir.actions.*(动作机制)- 作用:定义窗口动作、服务器动作、自动化流程等。
- 关键字段:
name、type、model_id。 - 典型用法:菜单跳转、自动任务、批量操作。
- 案例:定义窗口动作(XML)
<record id="action_partner_form" model="ir.actions.act_window"> <field name="name">联系人</field> <field name="res_model">res.partner</field> <field name="view_mode">tree,form</field> </record>
2.5 系统配置参数
-
ir.config_parameter- 作用:系统级参数存储,支持动态配置。
- 关键字段:
key、value。 - 典型用法:第三方集成、全局开关、动态配置。
- 案例:设置系统参数
env['ir.config_parameter'].set_param('my_module.api_key', 'abcdef123456')
-
res.config.settings- 作用:系统设置界面,封装参数读写逻辑。
- 关键字段:
config_parameter字段映射。 - 典型用法:后台设置、参数管理。
- 案例:通过设置界面修改参数(自动映射到 ir.config_parameter,无需手写代码)
2.6 控制器与 API 接入点(简要)
controllers/main.py- 作用:实现登录、登出、主页重定向、Web 客户管理等 HTTP 接口。
- 典型用法:Web 入口、API 扩展、第三方集成。
- 案例:自定义控制器添加登录接口
from odoo import http class MyController(http.Controller): @http.route('/my/login', type='json', auth='public') def my_login(self, db, login, password): uid = http.request.session.authenticate(db, login, password) return {'uid': uid}
3. ir.http 文件详解(Odoo 18)
Odoo Web 框架的核心,所有 HTTP 请求都经过 ir.http 的统一调度与分发。
3.1 位置与作用
- 文件位置:通常为
odoo/addons/base/ir/ir_http.py或odoo/ir/http.py(随 Odoo 版本略有不同) - 核心作用:Odoo HTTP 路由与请求分发的底层实现,负责将外部 HTTP 请求映射到 Odoo 控制器,处理 session、权限、CSRF 校验、多公司/多语言切换等。
3.2 主要职责
- 路由注册与分发(URL 到 Controller 方法的映射)
- 请求上下文(如用户、语言、公司、数据库)的初始化
- Session 管理与 CSRF 防护
- 权限与访问控制的前置校验
- 静态文件(如图片、JS、CSS)分发
- 处理 404/500 等异常
3.3 关键类与方法
class Http:Odoo HTTP 框架基类,负责路由注册、请求分发等。class IrHttp:Odoo 业务层的 HTTP 入口,继承自Http,实现 Odoo-specific 的请求处理逻辑。
主要方法:
dispatch():Odoo HTTP 请求的总入口。负责初始化上下文(如 env、user、lang、company),然后分发到对应的 Controller。authenticate():处理用户认证(如登录、token 校验),设置request.env.user。session_info():返回当前 session 的信息(如用户、公司、权限等),常用于前端初始化。get_request():获取当前 HTTP 请求对象。get_db():获取当前请求对应的数据库名。get_lang():获取当前请求的语言。get_company():获取当前请求的公司(多公司支持)。add_route():注册新的 HTTP 路由,通常由 Controller 装饰器自动调用。
3.4 典型请求流程(伪代码)
ir.http.dispatch 的核心流程:
# 1. 解析请求上下文(db, user, lang, company)
# 2. 权限/CSRF/session 校验
# 3. 路由分发到 Controller
# 4. 处理异常,返回 HTTP 响应
3.5 常见用法举例
-
注册自定义路由(自定义 Controller 的标准写法)
from odoo import http class MyController(http.Controller): @http.route('/my/hello', type='http', auth='public') def hello(self, **kw): return "Hello, Odoo!"这里的
@http.route实际上调用了 ir.http 的路由注册机制。 -
获取请求上下文(在 Controller 或业务代码中获取当前用户、语言、数据库等)
from odoo.http import request def my_method(): user = request.env.user lang = request.context.get('lang') db = request.db -
处理静态文件
访问
/web/static/路径时,ir.http 会自动分发静态资源。 -
多公司/多语言切换
ir.http 会根据 URL 参数或 session 自动切换
request.env.company和request.context['lang']。
3.6 典型源码片段(Odoo 18)
ir.http 主要方法结构示例:
class IrHttp(Http):
@classmethod
def dispatch(cls):
# 1. 解析请求上下文
# 2. 权限/CSRF/session 校验
# 3. 路由分发到 Controller
# 4. 处理异常,返回 HTTP 响应
pass
@classmethod
def authenticate(cls):
# 用户认证逻辑
pass
@classmethod
def session_info(cls):
# 返回 session 信息
pass
、、

进阶阅读推荐:
心有猛虎,细嗅蔷薇

浙公网安备 33010602011771号