有没有比覆盖整个函数更好的方法?

Are there better ways than overwriting a whole function?

在最近的项目中,我必须向模型添加自定义字段。使其正常工作的部分解决方案是覆盖“@api.onchange('')”函数。我只需要向词典中添加两个条目,但由于这是在一个循环中,所以除了复制整个函数并修改它之外,我没有看到其他解决方案。

我必须修改的函数是 sale.order 的一部分,之前被 website_quote 修改过。

这是我必须修改的功能:

@api.onchange('template_id')
def onchange_template_id(self):
    if not self.template_id:
        return
    template = self.template_id.with_context(lang=self.partner_id.lang)

    order_lines = [(5, 0, 0)]
    for line in template.quote_line:
        discount = 0
        if self.pricelist_id:
            price = self.pricelist_id.with_context(uom=line.product_uom_id.id).get_product_price(line.product_id, line.product_uom_qty, False)
            if self.pricelist_id.discount_policy == 'without_discount' and line.price_unit:
                discount = (line.price_unit - price) / line.price_unit * 100
                # negative discounts (= surcharge) are included in the display price
                if discount < 0:
                    discount = 0
                else:
                    price = line.price_unit

        else:
            price = line.price_unit

        data = {
            'name': line.name,
            'price_unit': price,
            'discount': 100 - ((100 - discount) * (100 - line.discount)/100),
            'product_uom_qty': line.product_uom_qty,
            'product_id': line.product_id.id,
            'layout_category_id': line.layout_category_id,
            'product_uom': line.product_uom_id.id,
            'website_description': line.website_description,
            'state': 'draft',
            'customer_lead': self._get_customer_lead(line.product_id.product_tmpl_id),
        }
        if self.pricelist_id:
            data.update(self.env['sale.order.line']._get_purchase_price(self.pricelist_id, line.product_id, line.product_uom_id, fields.Date.context_today(self)))
        order_lines.append((0, 0, data))

    self.order_line = order_lines
    self.order_line._compute_tax_id()

    option_lines = [(5, 0, 0)]
    for option in template.options:
        if self.pricelist_id:
            price = self.pricelist_id.with_context(uom=option.uom_id.id).get_product_price(option.product_id, 1, False)
        else:
            price = option.price_unit
        data = {
            'product_id': option.product_id.id,
            'layout_category_id': option.layout_category_id,
            'name': option.name,
            'quantity': option.quantity,
            'uom_id': option.uom_id.id,
            'price_unit': price,
            'discount': option.discount,
            'website_description': option.website_description,
        }
        option_lines.append((0, 0, data))
    self.options = option_lines

    if template.number_of_days > 0:
        self.validity_date = fields.Date.to_string(datetime.now() + timedelta(template.number_of_days))

    self.website_description = template.website_description
    self.require_payment = template.require_payment

    if template.note:
        self.note = template.note

如果您选择模板来创建销售订单,此方法负责显示销售模板的值。

我只需将我的自定义字段的名称添加到数据字典中即可获得正确的结果。

但在我看来,我是通过复制整个函数来暴力解决这个问题的。有没有更好的方法将我的更改插入到这样的函数中?

简短回答:不,没有更好的方法。

长答案:如果您的代码部分容易更改,则应将它们与函数体的其余部分分开。 因此,如果您将来要进行大量更改,请尝试重写该函数,这样它将从外部获取 data 变量。