Un par de veces me he encontrado con una situación, cuando al momento de ahorrar necesito saber qué campos de modelo se van a actualizar y actuar en consecuencia.Realizando un seguimiento de los cambios desde el último guardado en los modelos django
La solución más obvia de esto es tomar el campo de clave principal y recuperar una copia del modelo a partir de la base de datos:
class MyModel(models.Model):
def save(self, force_insert=False, force_update=False, using=None):
if self.id is not None:
unsaved_copy = MyModel.objects.get(id=self.id)
# Do your comparisons here
super(MyModel, self).save(force_insert, force_update, using)
que funciona perfectamente bien, sin embargo, que llega a la base de datos para cada instancia de el modelo que está guardando (puede ser bastante incómodo si realiza muchos de esos intentos).
Es obvio que si uno puede "recordar" los valores del campo anterior al inicio de la vida de la instancia del modelo (__init__
), no debería haber necesidad de recuperar una copia del modelo de la base de datos. Así me ocurrió con este pequeño truco:
class MyModel(models.Model):
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)
self.unsaved = {}
for field in self._meta.fields:
self.unsaved[field.name] = getattr(self, field.name, None)
def save(self, force_insert=False, force_update=False, using=None):
for name, value in self.unsaved.iteritems():
print "Field:%s Old:%s New:%s" % (name, value, getattr(self, name, None))
# old values can be accessed through the self.unsaved member
super(MyModel, self).save(force_insert, force_update, using)
Esto parece funcionar, sin embargo, hace uso de la interfaz no pública de django.db.models.Model
.
¿Quizás alguien sepa una manera más limpia de hacerlo?
No, no estaba preguntándolo en el contexto de las plantillas de administrador, sin embargo, verificará cómo se hace allí, gracias por la sugerencia. – shylent