Hay muchas formas de resolver el problema que has descrito:
- Lógica de aplicación
- Lógica específica de vista -- Si el comportamiento es específico de una sola vista, coloque los cambios en la vista.
- Lógica específica del modelo -- Si el comportamiento es específico de un solo modelo, entonces anular el método save() para el modelo.
- Lógica de software intermedio -- Si el comportamiento se relaciona con múltiples modelos O necesita ajustarse a una aplicación existente, puede usar señales de pre-guardado/post-guardado para agregar comportamientos adicionales sin cambiar la aplicación en sí.
- Procedimientos almacenados en la base de datos -- Normalmente es una posibilidad, pero el ORM de Django no los usa. No es portátil entre bases de datos.
- Activadores de base de datos -- No es portátil de una base de datos a otra (o incluso de una versión de una base de datos a la siguiente), pero le permite controlar el comportamiento compartido en varias aplicaciones (posiblemente no Django).
Personalmente, prefiero anular el método save() o usar una señal de Django. El uso de la lógica específica de vista puede atraparlo en aplicaciones grandes con múltiples vistas del mismo modelo.