odoo開發中@api.depends與@api.onchange的區別


@api.depends

這個裝飾器主要運用在odoo的字段相關的函數中。在函數中,對該字段值進行處理時,如果計算值依賴於其他相關字段,不論是與該字段隸屬同一張表的還是其他表的字段,都會觸發所編寫的字段函數。正因為此,可以利用@api.depends 裝飾來偵測與字段相關的其他表的字段。如果decorator中依賴的任何字段“被ORM更改或在表單中更改”,都將觸發對decorated函數的調用。

@api.onchange

這個裝飾器觸發decorated函數的時機是:定義的指定字段如果在form窗體出現了變化,就會觸發執行。這里要注意的是,這些字段是隸屬於同一個模型或同一界面。

綜上,雖然 @api.depends 與@api.onchange有諸多相似的地方,但一個重要區別就是 onchange 的偵測字段范圍需要在同一個模型或界面上;而depends 可以偵測關聯的模型的字段(可以跨不同表)。

 

    @api.onchange('product_uom_qty', 'product_uom', 'route_id')
    def _onchange_product_id_check_availability(self):
        if not self.product_id or not self.product_uom_qty or not self.product_uom:
            self.product_packaging = False
            return {}
        if self.product_id.type == 'product':
            precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
            product = self.product_id.with_context(
                warehouse=self.order_id.warehouse_id.id,
                lang=self.order_id.partner_id.lang or self.env.user.lang or 'en_US'
            )

上面這段代碼節選自sale_order.py 文件SaleOrderLine類中, 'product_uom_qty', 'product_uom', 'route_id' 這些字段都是定義在 sale.order.line 模型中的。

再看下面代碼中用到的depends:

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'

    qty_delivered_method = fields.Selection(selection_add=[('stock_move', 'Stock Moves')])
    product_packaging = fields.Many2one('product.packaging', string='Package', default=False)
    route_id = fields.Many2one('stock.location.route', string='Route', domain=[('sale_selectable', '=', True)], ondelete='restrict')
    move_ids = fields.One2many('stock.move', 'sale_line_id', string='Stock Moves')

    @api.multi
    @api.depends('product_id')
    def _compute_qty_delivered_method(self):
        """ Stock module compute delivered qty for product [('type', 'in', ['consu', 'product'])]
            For SO line coming from expense, no picking should be generate: we don't manage stock for
            thoses lines, even if the product is a storable.
        """
        super(SaleOrderLine, self)._compute_qty_delivered_method()

        for line in self:
            if not line.is_expense and line.product_id.type in ['consu', 'product']:
                line.qty_delivered_method = 'stock_move'

    @api.multi
    @api.depends('move_ids.state', 'move_ids.scrapped', 'move_ids.product_uom_qty', 'move_ids.product_uom')
    def _compute_qty_delivered(self):
        super(SaleOrderLine, self)._compute_qty_delivered()

這段代碼與上面onchange片段一樣都來自SaleOrderLine類,但可以看到 @api.depends('product_id') 中的product_id字段是不在sale.order.line模型中的。同樣,@api.depends('move_ids.state', 'move_ids.scrapped', 'move_ids.product_uom_qty', 'move_ids.product_uom') 也是跨表偵測字段。

從上面兩段代碼,就能看出兩者最主要的區別,另外從觸發來看,api.onchage在字段變化的時候會觸發一次,當字段內容變換完成保存的時候還會觸發一次。而api.depends則只在字段變化的時候觸發一次。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM