参考: https://hub.packtpub.com/handle-odoo-application-data-with-orm-api-tutorial/
一、特殊装饰器
@api.multi 默认有这个装饰器, 需要一个自定义方法来对记录集作操作
@api.one 单一记录操作
@api.model 该方法在类级别操作,此时self是模型的参考
二、特殊方法
查
search()
browse()
增改删
create(values) 在模型新增记录时触发
write(values) 修改时触发
unlink() 删除时触发
在某些情况下, 我们需要扩展这些方法以添加一些业务逻辑, 以便在执行这些操作时触发
Python3通过super()函数执行上一个mro方法, 如: super(TodoTask, self).create(vals),;如果我不介意破坏Python支持, 可以不传引用类名和self参数,如super().create(vals)
自定义create()
@api.model def create(self, vals): # 执行前业务逻辑 ret = super(TodoTask, self).create(vals) # 自定义执行后业务逻辑 return ret
自定义write()
@api.multi def write(self, vals): # 业务逻辑 ret = super(TodoTask, self).write(vals) # 业务逻辑 return ret
总结1
扩展create、write给我们带来了更多的可能性, 但很多情况下我们不需要那样, 因为我们还有一些工具更适合,比如:
1 基于其他字段自动计算字段值, 应该使用【计算字段】(例子: 当一个行数改变时,计算总数)
2 要动态计算[字段默认值], 我们可以给字段绑定一个【函数】, 而不是一个固定值
3 在更改字段时在其他字段上设置值, 我们可以使用【onchange】函数 (例子:当选择一个客户时,将其货币设为文档的货币, 以后可以由用户手动更改)。注意: 仅适用于form表单交互, 不适用于【直接】写入调用, 但是表单save时, 将会写入
总结2
使用自定create,write之前认真考虑
1 用得更多的情况是:
- 保存记录时执行一些验证
- 保存记录时自动计算某些字段
2 出于某种原因, 计算字段和contraints不是有效的解决方案时, 最好的方法时将我们的逻辑写在自定义create/write方法上, 并将所需的更改累积到将传递给super()调用的vals字典中
注意
对于write()方法, 在同一模型上进一步的写操作将导致递归循环, 并在工作进程资源耗尽时报错
解决办法:在context设置一个表示是
例如:
if not self.env.context.get('todo_task_writing'): # 找不到特殊标记才运行 self.with_context(todo_task_writing=True).write(somevalues) # 第一次来时设置上特殊标记, 第二次不进这个if了