odoo11 ORM API指南

参考: 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了
原文地址:https://www.cnblogs.com/sunch/p/10763976.html