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

相关推荐
mortimer17 分钟前
Python 进阶:彻底理解类属性、类方法与静态方法
后端·python
知其然亦知其所以然25 分钟前
SpringAI让Java会画画?用Azure OpenAI生成AI图片太惊艳了!
后端·spring·openai
BugShare25 分钟前
XSS检测绕过(UTF-7编码绕过)
后端
ZhengEnCi27 分钟前
统一认证平台完全指南-从单点登录到企业级安全访问的数字化利器
后端
9号达人29 分钟前
if-else 优化的折中思考:不是消灭分支,而是控制风险
java·后端·面试
回家路上绕了弯44 分钟前
高并发后台系统设计要点:从流量削峰到低延迟的实战指南
分布式·后端
Yefimov1 小时前
3. DPDK:更好的压榨cpu--并行计算
后端
两万五千个小时1 小时前
LangChain 入门教程:06LangGraph工作流编排
人工智能·后端
oak隔壁找我1 小时前
MyBatis的MapperFactoryBean详解
后端
王道长AWS_服务器1 小时前
AWS Elastic Load Balancing(ELB)—— 多站点负载均衡的正确打开方式
后端·程序员·aws