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

相关推荐
IT_陈寒几秒前
SpringBoot这个坑差点让我加班到天亮
前端·人工智能·后端
小小龙学IT3 分钟前
Go 后端开发中的并发模式:从 Goroutine 到 Pipeline 实战
开发语言·后端·golang
geovindu31 分钟前
go: Coroutines Pattern
开发语言·后端·设计模式·golang·协程模式
阿正的梦工坊1 小时前
【Rust】01-认识 Rust:语言定位、工具链与第一个程序
开发语言·后端·rust
一条泥憨鱼1 小时前
苍穹外卖【day5|Redis与店铺营业状态设置】
java·后端·mybatis·苍穹外卖
uzong1 小时前
企业智能助手的实践分享(LLM/RAG)
后端·程序员·架构
GetcharZp9 小时前
GitHub 49K+ Star!C++ 开发者必知的 JSON 神级库:从零到精通全指北
后端
xujinwei_gingko9 小时前
SpringBoot整合WebSocket
spring boot·后端·websocket
智码看视界10 小时前
现代Web开发基础:全栈工程师的起航点
前端·后端·c5全栈