odoo利用postsql表的继承性实现父模型与子模型记录同步

23 篇文章 0 订阅
23 篇文章 1 订阅

如果遇到有些场景中,多个模型有很多相同字段或者相同功能,可以通过postsql的表继承特性,将多个模型抽象出一个父模型,将相同功能和相同字段放到父模型当中,独特的有差异的字段或者属性放到子模型中,这样子表的记录和父表的记录可以保持一致,增删改查保持同步

缺点:需要修改框架底层代码
**

实现方式可以参照ir.actions.actions模型及其子模型的实现方式,在odoo框架自带模块中的odoo/odoo/addons/base模块中

**
具体实现方式如下:
需要定义一个sql文件,先创建出子父级表的表名和继承关系,我这里放在模块的data目录下面,命名为base_data.sql

CREATE TABLE if not exists 父模型表名称 (
  id serial,
  primary key(id)
);
CREATE TABLE if not exists 子模块1表名 (primary key(id)) INHERITS (父模型表名称);
CREATE TABLE if not exists 子模块2表名 (primary key(id)) INHERITS (父模型表名);
CREATE TABLE if not exists 子模块3表名 (primary key(id)) INHERITS (父模型表名);

父表和子表需要一个相同字段,用于保存父表记录时区分是哪个子表的记录.

import odoo.modules
import logging

_logger = logging.getLogger(__name__)


class 父表模型类名(models.Model):
	_name = '父表模型名'
	_table = '当前模型在数据库中存的表的名称'
	
	type = fields.Char(string='子表记录') #用于区分是哪个子表的记录
	# ......字段定义

	def init(self):
        '''
        执行data目录下的sql文件,建立数据库中物资相关表的表继承关系
        '''
        f = odoo.modules.get_module_resource('sql文件所在模块名称', 'sql文件所在目录(如data)', 'base_data.sql')
        if not f:
            m = "File not found: 'base.sql' (provided by module 'base')."
            _logger.critical(m)
            raise IOError(m)

        with odoo.tools.misc.file_open(f) as base_sql_file:
            self._cr.execute(base_sql_file.read())

子表:子模型示例如下

class 子表模型名(models.Model):
	_name = '子模型名称'
	_table = '子模型数据库保存的表名称' # 需要和sql文件中定义的保持一致
	
	type = fields.Char(default='子表模型名称(_name属性定义的名称)') # 用于父表中区分记录是哪个子表的,用_name容易区分,也可以保存其他的字符串区分
	# ......其他字段定义

最后一步:修改fields.py中更新外键函数
文件路径为:odoo/odoo/fields.py

    def update_db_foreign_key(self, model, column):
        comodel = model.env[self.comodel_name]
        # foreign keys do not work on views, and users can define custom models on sql views.
        if not model._is_an_ordinary_table() or not comodel._is_an_ordinary_table():
            return
        # ir_actions is inherited, so foreign key doesn't work on it

		**

此处需要新增or关系判断字段是不是关联父模型,和ir.actions.actions一样,跳过创建外键的逻辑

**
        if not comodel._auto or comodel._table == 'ir_actions' or comodel._table == '父模型表名称':
            return
        # create/update the foreign key, and reflect it in 'ir.model.constraint'
        process = sql.fix_foreign_key if column else sql.add_foreign_key
        new = process(model._cr, model._table, self.name, comodel._table, 'id', self.ondelete or 'set null')
        if new:
            conname = '%s_%s_fkey' % (model._table, self.name)
            model.env['ir.model.constraint']._reflect_constraint(model, conname, 'f', None, self._module)

这样就可以实现父模型和子模型记录保持同步

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值