5. Valores, cálculos y cambios
Objetivos
- distinguir valores por defecto, on_change, Function y campos almacenados
- mantener coherentes la ayuda del cliente y la validación del servidor
- evitar patrones costosos de campos calculados
Modelo mental
Este concepto debe entenderse como parte de un sistema transaccional: la interfaz ayuda al usuario, el servidor conserva las reglas y la base persiste el resultado. Los valores por defecto inicializan; on_change ayuda en formularios sin guardar; Function calcula o representa; la validación protege cualquier vía de escritura. La comodidad no equivale a integridad.
Práctica guiada
- Inicialice valores seguros con default_CAMPO.
- Declare depends para todo campo leído por on_change.
- Use Function cuando sus semánticas de cálculo o representación lo justifiquen.
- Añada searcher si el usuario debe filtrar el valor calculado.
- Proteja la regla definitiva en el servidor.
Ejemplo mínimo
from decimal import Decimal
from trytond.model import ModelSQL, ModelView, fields
class Book(ModelSQL, ModelView):
__name__ = 'library.book'
price = fields.Numeric("Price", required=True, digits=(16, 2))
discount = fields.Numeric("Discount", digits=(16, 2))
net_price = fields.Function(
fields.Numeric("Net Price", digits=(16, 2)),
'get_net_price')
@classmethod
def default_discount(cls):
return Decimal('0.00')
def get_net_price(self, name):
return (self.price or Decimal(0)) - (self.discount or Decimal(0))
Cómo leer el ejemplo
En lotes, prefiera un getter de clase cuando evite una consulta por registro. Si net_price se busca mucho o debe preservar historia, puede convenir un campo almacenado actualizado de forma controlada.
Ejercicio
Añada un límite de descuento, respuesta inmediata de on_change y una prueba de validación del servidor que omita el cliente.
Realice el ejercicio primero con un caso mínimo, después agregue un caso inválido y convierta ambos en pruebas repetibles.
Resultado verificable
El formulario responde inmediatamente, las importaciones y RPC respetan la misma regla y listar 100 libros no genera consultas evitables por fila.
Errores frecuentes
- poner seguridad en on_change
- olvidar depends
- calcular dinero con flotantes binarios
- usar campos Function sin searcher como filtros
Criterio para avanzar
- Puedo explicar la diferencia entre los conceptos sin mirar el código.
- El caso válido y el inválido tienen pruebas.
- Probé con un usuario sin privilegios administrativos.
- Sé cómo actualizar y cómo recuperar la base de entrenamiento.
Versión y referencias
La serie 7.0 requiere como mínimo Python 3.8 según los metadatos oficiales. Esta rama oficial todavía conserva metadatos históricos en setup.py; mantenga compatibilidad con la serie, pero prepare sus paquetes personalizados para la construcción estándar mediante python -m build. No confunda ese mínimo histórico con la versión de Python que haya certificado su organización.
Esta edición fija ejemplos y dependencias en la serie 7.0. Consulte el tutorial oficial 7.0, la API del servidor y el código de esa rama antes de trasladar el patrón a producción.