Decorador depends()
Os campos calculados geralmente dependem dos valores de outros campos dentro de um registro. O ORM requer que os desenvolvedores utilizem o decorador depends() para indicar essas dependências no método de cálculo. Essas dependências são empregadas pelo ORM para disparar o recálculo do campo quando qualquer uma delas é modificada:
from odoo import api, fields, models
class ExemploCalculado(models.Model):
_name = "exemplo.calculado"
resultado = fields.Float(compute="_calcular_resultado")
entrada = fields.Float()
@api.depends("entrada")
def _calcular_resultado(self):
for item in self:
item.resultado = 2.0 * item.entrada
Ao alterar o campo entrada, a função _calcular_resultado é executada, atualizando automaticamente o valor de resultado.
Função Inversa
Campos calculados são tipicamente somente leitura. Entretanto, em situações específicas, permitir a definição direta do valor pode ser vantajoso. O Odoo suporta isso através de uma função inversa.
class ExemploCalculado(models.Model):
_name = "exemplo.calculado"
resultado = fields.Float(compute="_calcular_resultado", inverse="_inverter_resultado")
entrada = fields.Float()
@api.depends("entrada")
def _calcular_resultado(self):
for item in self:
item.resultado = 2.0 * item.entrada
def _inverter_resultado(self):
for item in self:
item.entrada = item.resultado / 2.0
Gatilho onchange()
O mecanismo 'onchange' permite atualizar a interface do usuário em tempo real sem persistir dados no banco de dados. Para isso, um método é definido com self referenciando o registro no formulário, decorado com onchange() para especificar os campos que o ativam. Alterações em self são imediatamente refletidas no formulário:
from odoo import api, fields, models
class FormularioDinamico(models.Model):
_name = "formulario.dinamico"
titulo = fields.Char(string="Título")
resumo = fields.Char(string="Resumo")
cliente_id = fields.Many2one("res.partner", string="Cliente")
@api.onchange("cliente_id")
def _ao_mudar_cliente(self):
self.titulo = "Documento para %s" % (self.cliente_id.name)
self.resumo = "Resumo padrão para %s" % (self.cliente_id.name)
Neste cenário, mudar o cliente atualiza título e resumo. Os usuários podem modificar esses valores manualmente após a atualização automática. Note que self não é iterado, pois o método só é acionado no formulário, onde self representa um único registro.