前两天写了一个很好玩的功能,一是感觉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的可玩性很高)