Puede hacer esto en un método reemplazado save
. Lo que hay que recordar es que las instancias del modelo Django no son los objetos reales de la base de datos, solo obtienen sus valores desde allí en carga. De modo que puede volver fácilmente a la base de datos antes de guardar su objeto actual para obtener los valores existentes.
def save(self, *args, **kwargs):
if self.status == 'pending':
old_instance = MyClass.objects.get(pk=self.pk)
if old_instance.status == 'activated':
raise SomeError
super(MyModel, self).save(*args, **kwargs)
Actualmente no hay una buena manera de devolver un mensaje de error al usuario que no sea el de generar una excepción. Existe un proyecto Google Summer of Code actualmente en curso para habilitar la 'validación del modelo', pero esto no estará listo durante unos meses.
Si desea hacer algo similar en el administrador, la mejor manera es definir un Modelo de formulario personalizado con un método reemplazado clean()
. Sin embargo, esta vez dado que se trata de un formulario, ya tiene acceso a los valores anteriores sin presionar nuevamente el db. Otro beneficio es que puede devolver un error de validación de formulario al usuario.
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def clean_status(self):
status = self.cleaned_data.get('status', '')
if status == 'pending':
if self.instance and self.instance.status == 'activated':
raise forms.ValidationError(
'You cannot change activated to pending'
)
return status
class MyModelAdmin(forms.ModelAdmin):
form = MyModelForm
model = MyModel
+1 - Me he estado preguntando lo mismo.En mi caso, hay un trabajo pesado que se hace en un método de guardado que solo es necesario si un campo en un subconjunto particular de los campos del modelo ha cambiado, y he estado buscando una forma de verificar si este es el caso . ¡Gracias! –