odoo中为动态模型添加记录规则

前两天写了一个很好玩的功能,一是感觉odoo中可以挖掘的东西还很多,二是感觉这个东西的实现很好玩。

前情提要:当时有个需求是更改模型的记录规则,要更改的模型呢,有点特别。因为它是自定义的模型,叫什么名字你并不能确定下来,当时的思路是重写动态模型的搜索方法,可是实践之后发现比较麻烦。当时都想直接手动修改对应模型的记录规则来实现呢,后来觉得更加麻烦。再问了众多AI后,就感觉可以直接将对应模型的记录规则写入数据库中,对于后续新添加的模型可以通过定时任务的方式来进行添加。

一个记录规则,包含规则名称、模型id、domain、用户组,我们组合对应的数据就可以了。

这个代码是获取符合要求的动态模型

python 复制代码
    @api.model
    def load_record_rules(self):
        """动态为审批模型添加记录规则"""
        custom_models = self.env['ir.model'].search([('model', 'ilike', 'x_%')])
        required_fields = ['x_subject', 'x_description', 'x_priority']

        for model in custom_models:
            fields = self.env['ir.model.fields'].search_read(
                [('model', '=', model.model), ('name', 'in', required_fields)],
                fields=['name'],
            )
            field_names = [f['name'] for f in fields]

            # 如果字段齐全,则添加记录规则到模型
            if all(field in field_names for field in required_fields):
                _logger.info(f'Loading rules for model: {model.model}')
                self._add_user_rule(model.model)
                self._add_admin_rule(model.model)

这是添加对应用户组的记录规则的方法

python 复制代码
    def _add_user_rule(self, model_name):
        """为普通用户添加记录规则"""
        _logger.info(f'Adding user rule for model: {model_name}')
        self._create_rule(
            model_name=model_name,
            rule_domain="[('create_uid', '=', user.id)]",  # 普通用户只能查看自己创建的记录
            rule_name=f'User Access Rule for {model_name}',
            group_xml_id='base.group_user',  # 普通用户组
        )

核心代码,创建记录规则

python 复制代码
    def _create_rule(self, model_name, rule_domain, rule_name, group_xml_id):
        """创建记录规则"""
        rule_obj = self.env['ir.rule']

        # 检查是否已经存在同名规则
        existing_rule = rule_obj.search(
            [('name', '=', rule_name), ('model_id.model', '=', model_name)]
        )
        if existing_rule:
            _logger.info(
                f"Rule '{rule_name}' already exists for model '{model_name}', skipping creation."
            )
            return

        # 获取目标模型的 ID
        model = self.env['ir.model'].search([('model', '=', model_name)], limit=1)
        if not model:
            raise ValueError(
                f"Model '{model_name}' not found in 'ir.model'. Please check if it's properly registered."
            )

        # 获取用户组(如果指定)
        groups = [(4, self.env.ref(group_xml_id).id)] if group_xml_id else []

        # 创建记录规则
        rule_obj.create(
            {
                'name': rule_name,
                'model_id': model.id,
                'domain_force': rule_domain,
                'groups': groups,  # 仅应用于特定用户组
            }
        )
        _logger.info(f"Rule '{rule_name}' created for model '{model_name}'.")

总结,只要是在数据库中存放的数据都可以通过这种方式来进行修改和添加(odoo的可玩性很高)

相关推荐
阳光是sunny2 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
灯澜忆梦2 小时前
GO_并发编程---定时器
开发语言·后端·golang
阳光是sunny2 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
皮皮林5512 小时前
开源实力派,给本地 AI 装上深度调研能力,一张 3090 跑到 95.7 分!
后端
努力的小雨3 小时前
把 Windows 桌面图标做成一个会自己运转的小世界
后端
武子康4 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
腾渊信息科技公司4 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
IT_陈寒6 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学6 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈6 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端