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的可玩性很高)

相关推荐
码农阿豪2 小时前
Flask应用上下文问题解析与解决方案:从错误日志到完美修复
后端·python·flask
威迪斯特2 小时前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
毕设源码-钟学长3 小时前
【开题答辩全过程】以 基于Springboot的扶贫众筹平台为例,包含答辩的问题和答案
java·spring boot·后端
程序员良许3 小时前
三极管推挽输出电路分析
后端·嵌入式
Java水解4 小时前
【JAVA 进阶】Spring AOP核心原理:JDK与CGLib动态代理实战解析
后端·spring
Java水解4 小时前
Spring Boot 4 升级指南:告别RestTemplate,拥抱现代HTTP客户端
spring boot·后端
宫水三叶的刷题日记4 小时前
工商银行今年的年终奖。。
后端
大黄评测4 小时前
双库协同,各取所长:.NET Core 中 PostgreSQL 与 SQLite 的优雅融合实战
后端
Java编程爱好者4 小时前
Java 后端定时任务怎么选:@Scheduled、Quartz 还是 XXL-Job?
后端
Java编程爱好者4 小时前
线程池用完不Shutdown,CPU和内存都快哭了
后端