字段示例:
supplier_id = fields.Many2one('res.partner',
string='Preferred supplier',
compute="_compute_supplier_id",
store=True)
@api.multi
@api.depends('product_id', 'product_id.seller_ids')
def _compute_supplier_id(self):
for rec in self:
if rec.product_id:
if rec.product_id.seller_ids:
rec.supplier_id = rec.product_id.seller_ids[0].name
源码分析:
@api.model
def recompute(self):
""" Recompute stored function fields. The fields and records to
recompute have been determined by method :meth:`modified`.
"""
while self.env.has_todo():
field, recs = self.env.get_todo()
# determine the fields to recompute
fs = self.env[field.model_name]._field_computed[field]
ns = [f.name for f in fs if f.store]
# evaluate fields, and group record ids by update
updates = defaultdict(set)
for rec in recs:
try:
vals = {n: rec[n] for n in ns}
except MissingError:
continue
vals = rec._convert_to_write(vals)
updates[frozendict(vals)].add(rec.id)
# update records in batch when possible
with recs.env.norecompute():
for vals, ids in updates.items():
target = recs.browse(ids)
try:
target._write(dict(vals))
except MissingError:
# retry without missing records
target.exists()._write(dict(vals))
# mark computed fields as done
for f in fs:
recs._recompute_done(f)
说明:
- 带
store=True
的compute 字段,compute
方法会根据api.depends
的字段变化来执行.
- 有时候我们无意之中改了某个表中的数据,上例中改了
product.product
中的seller_ids
就会触发 _compute_supplier_id
方法.
- 假如存在多公司的情况,就得考虑公司是否一直的情况了,不然会报错.