odoo 关于compute+store 字段的分析

字段示例:

    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)

说明:

  1. store=True 的compute 字段,compute 方法会根据api.depends的字段变化来执行.
  2. 有时候我们无意之中改了某个表中的数据,上例中改了product.product 中的seller_ids就会触发 _compute_supplier_id 方法.
  3. 假如存在多公司的情况,就得考虑公司是否一直的情况了,不然会报错.
posted @ 2021-06-08 16:26  那时一个人  阅读(462)  评论(0编辑  收藏  举报