为何project_id字段约束未被触发?如何使其生效?
看起来你遇到的是Odoo中约束(constrains)未正确触发的典型问题,我来帮你一步步排查和解决:
1. 修正装饰器:弃用@api.one
在Odoo 10及以后的版本中,@api.one已经被弃用,并且会导致约束方法无法正确遍历记录。你需要移除@api.one装饰器,改用@api.multi(或者直接只保留@api.constrains,因为新版本中@api.constrains默认支持多记录处理)。
修改后的代码应该是这样的:
from odoo import models, api, exceptions class AccountAnalyticLine(models.Model): _inherit = 'account.analytic.line' @api.constrains('project_id') def constrain_project_id(self): # 遍历每条记录进行校验 for record in self: # 这里可以添加你的具体校验逻辑,比如判断项目是否符合特定条件 if record.project_id: raise exceptions.ValidationError('Working')
2. 检查模块依赖与加载顺序
确保你的自定义模块在__manifest__.py中正确声明了依赖项,因为AccountAnalyticLine属于account模块,而hr_timesheet是扩展它的模块,所以你的模块必须依赖这两个模块:
# __manifest__.py { 'name': 'Your Custom Module', 'depends': ['account', 'hr_timesheet'], # 其他配置项... }
如果你的模块依赖顺序不对,或者没有声明依赖,继承逻辑可能不会生效,导致约束方法从未被加载。
3. 确保模块已升级并重启服务
修改代码后,一定要在Odoo后台升级你的自定义模块,必要时重启Odoo服务。有时候旧的代码缓存会导致修改不生效,这是很多开发者容易忽略的点。
4. 验证约束触发的时机
Odoo的@api.constrains只有在指定字段被**创建(create)或修改(write)**时才会触发,所以测试时要注意:
- 创建一条新的工时记录,选择项目后保存,看是否弹出错误提示
- 编辑已有的工时记录,修改项目字段后保存,验证约束是否触发
如果你的前端表单通过domain限制了可选项目(比如hr_timesheet中的domain=[('allow_timesheets', '=', True)]),那么用户只能选择符合条件的项目,但约束仍然会在保存时触发——哪怕项目是符合domain的,你的测试代码(直接抛错)也应该生效。
5. 排查是否有其他模块覆盖逻辑
如果以上步骤都做了还是不行,检查是否有其他自定义模块也继承了AccountAnalyticLine并修改了project_id字段或约束。Odoo的模块加载顺序会影响继承优先级,确保你的模块在其他修改该模型的模块之后加载(可以通过调整模块的sequence或者依赖顺序来实现)。
按照这些步骤排查,你的约束应该就能正常触发了。
内容的提问来源于stack exchange,提问作者hakon80

