Odoo模块演示数据异常:首条记录未触发Create方法
我正尝试为Odoo模块添加演示数据,其中一个模型继承了res.partner并重写了create方法,该方法实现两个逻辑:
- 验证当前用户是否属于指定用户组;
- 通过序列为
patient_number字段赋值。
对应的Python代码:
@api.model def create(self, vals_list): if not self.env.user.has_group('my-project.group_super') and not self.env.user.has_group( 'my-project.group_some_other_group'): raise ValidationError( f"Warning! You have no permission to create a patient. Contact your administrator") vals_list['patient_number'] = self.env['ir.sequence'].next_by_code('my-project.res.partner') return super(Patient, self).create(vals_list)
触发的ValidationError提示:
Warning! You have no permission to create a patient. Contact your administrator
在演示数据XML文件中,第一条记录(id为johnsmith)加载后可显示,但patient_number字段未填充;复制该记录并修改id为johnsmith2后,加载演示数据时触发上述权限错误,日志报错且加载失败。看起来第一条记录未被重写的create方法处理,第二条则被处理。
补充用户组定义XML:
<record id="my_project" model="ir.module.category"> <field name="name">My Project</field> <field name="description">Users groups for My project</field> </record> [...] <record id="group_super" model="res.groups"> <field name="name">Supervisor</field> <field name="category_id" ref="my-project.my_project"/> </record> [...] <record id="group_some_other_group" model="res.groups"> <field name="name">Some Other Group</field> <field name="category_id" ref="my-project.my_project"/> </record>
ir.model.access.csv相关配置:
sc_study_partner_super,res.partner.super,model_res_partner,group_super,1,1,1,1 [...] sc_study_partner_some_other_role,res.partner.some_other_role,model_res_partner,group_some_other_group,1,1,1,1
演示数据文件demo/patients.xml未设置no update标记。
1. 第一条记录patient_number为空的原因
模块首次安装时,演示数据的加载顺序大概率早于序列my-project.res.partner的定义文件。此时调用next_by_code会因序列不存在返回None,导致patient_number字段无值。同时,Odoo加载演示数据默认使用超级用户(user_root)上下文,超级用户调用has_group会直接返回True,所以权限校验通过,记录能正常创建。
2. 第二条记录触发权限错误的原因
模块升级时,新增的johnsmith2记录不存在,Odoo会执行create方法。若此时操作模块的用户(比如admin)未被分配到group_super或group_some_other_group,has_group返回False,触发ValidationError。而第一条记录因已存在,Odoo执行的是write操作,不会触发重写的create方法,因此无报错。
另外,演示数据未设置noupdate="1",会导致模块升级时Odoo重复处理已有记录,但不会补全patient_number空值,因为write方法未处理该字段的赋值逻辑。
- 调整XML加载顺序:在模块的
__manifest__.py的data列表中,将序列my-project.res.partner的定义文件放在演示数据文件之前,确保加载演示数据时序列已存在。 - 给操作用户分配权限组:将执行模块安装/升级的用户(如
admin)添加到group_super或group_some_other_group中,避免权限校验失败。 - 补充
write方法逻辑(可选):若需要补全已有记录的patient_number空值,可重写write方法,在字段为空时自动赋值序列。 - 演示数据添加
noupdate="1":在演示数据的<record>标签中添加noupdate="1",避免模块升级时Odoo重复处理已有演示记录。
内容的提问来源于stack exchange,提问作者user1632812

