第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(权限组)

    • 作用:权限分组,控制菜单、字段、操作的可见性和可用性。
    • 关键字段namecategory_idusers
    • 典型用法:角色管理、功能授权。
    • 案例:为权限组分配菜单访问权限(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(联系人/公司)

    • 作用:统一管理客户、供应商、员工、公司等一切"联系人"。
    • 关键字段nameemailphonecompany_type
    • 典型用法:客户关系、供应链、员工档案。
    • 案例:创建联系人并指定为公司
      partner = env['res.partner'].create({
          'name': '某科技有限公司',
          'company_type': 'company',
          'email': 'info@company.com',
      })
      
  • res.company(公司)

    • 作用:多公司支持,隔离数据、配置。
    • 关键字段namecurrency_idpartner_id
    • 典型用法:多公司账套、权限隔离。
    • 案例:新建公司并指定默认货币
      company = env['res.company'].create({
          'name': '分公司A',
          'currency_id': env.ref('base.USD').id,
      })
      
  • res.lang(语言)

    • 作用:多语言支持,定义系统可用语言及格式。
    • 关键字段codenamedate_format
    • 典型用法:本地化、国际化。
    • 案例:激活新语言
      lang = env['res.lang'].search([('code', '=', 'ja_JP')])
      if lang:
          lang.active = True
      
  • res.currency(货币)

    • 作用:多币种支持,管理汇率、符号等。
    • 关键字段namesymbolrate
    • 典型用法:财务、销售、采购多币种结算。
    • 案例:更新货币汇率
      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(字段注册表)

    • 作用:注册每个模型的字段,支持动态字段、字段权限。
    • 关键字段namemodel_idttype(字段类型)、required
    • 典型用法:动态表单、字段扩展、权限控制。
    • 案例:查询模型的所有字段
      fields = env['ir.model.fields'].search([('model', '=', 'res.partner')])
      for f in fields:
          print(f.name, f.ttype)
      

2.3 权限机制

  • ir.model.access(访问控制表)

    • 作用:定义模型的增删改查权限,按组分配。
    • 关键字段namemodel_idgroup_idperm_readperm_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 的数据行级权限控制。
    • 关键字段namemodel_iddomain_forcegroups
    • 典型用法:多公司、部门隔离、审批流。
    • 案例:为模型添加记录规则(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,支持升级、导入导出。
    • 关键字段modulenamemodelres_id
    • 典型用法:模块升级、数据迁移、外部集成。
    • 案例:通过 XML ID 获取数据
      partner = env.ref('base.main_partner')
      
  • ir.exports(导出模板)

    • 作用:保存用户自定义的数据导出字段模板。
    • 关键字段nameexport_fields
    • 典型用法:批量导出、定制报表。
    • 案例:保存自定义导出模板
      export = env['ir.exports'].create({
          'name': '导出联系人',
          'resource': 'res.partner',
          'export_fields': [(0, 0, {'name': 'name'}), (0, 0, {'name': 'email'})],
      })
      
  • ir.actions.*(动作机制)

    • 作用:定义窗口动作、服务器动作、自动化流程等。
    • 关键字段nametypemodel_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

    • 作用:系统级参数存储,支持动态配置。
    • 关键字段keyvalue
    • 典型用法:第三方集成、全局开关、动态配置。
    • 案例:设置系统参数
      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.pyodoo/ir/http.py(随 Odoo 版本略有不同)
  • 核心作用:Odoo HTTP 路由与请求分发的底层实现,负责将外部 HTTP 请求映射到 Odoo 控制器,处理 session、权限、CSRF 校验、多公司/多语言切换等。

3.2 主要职责

  1. 路由注册与分发(URL 到 Controller 方法的映射)
  2. 请求上下文(如用户、语言、公司、数据库)的初始化
  3. Session 管理与 CSRF 防护
  4. 权限与访问控制的前置校验
  5. 静态文件(如图片、JS、CSS)分发
  6. 处理 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.companyrequest.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

、、

进阶阅读推荐:


posted @ 2025-05-29 09:16  何双新  阅读(281)  评论(0)    收藏  举报