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

相关推荐
小璐资源网1 分钟前
从源码看ArrayList与LinkedList的性能差异
后端
紫丁香11 分钟前
Dify源码深度剖析3
后端·python·ai·flask·fastapi
IT_陈寒11 分钟前
JavaScript开发者必看:3个让代码效率翻倍的隐藏技巧
前端·人工智能·后端
希望永不加班17 分钟前
如何在 SpringBoot 里自定义 Spring MVC 配置
java·spring boot·后端·spring·mvc
Welcome_Back23 分钟前
SpringBoot后端开发测试全指南
spring boot·后端·log4j
大傻^32 分钟前
Spring AI Alibaba MCP协议实战:模型上下文协议集成与工具调用
java·人工智能·后端·spring·elasticsearch·springaialibaba
稻草猫.44 分钟前
MyBatis进阶:动态SQL与MyBatis Generator插件使用
java·数据库·后端·spring·mvc·mybatis
qq_256247051 小时前
Docker 部署 OpenClaw 踩坑实录:Web UI 访问、飞书配对及自定义模型配置
后端
困惑阿三1 小时前
全栈部署排雷手册:从 405 报错到飞书推送成功
服务器·前端·后端·nginx·阿里云·node.js·飞书
bug攻城狮1 小时前
为什么 Spring Boot 要单元测试?
spring boot·后端·单元测试