I have a status field which has 3 values: pending, activated and rejected. If I am changing the value of status I want to have a check that activated cannot be changed to pending. I do not want to write stored-procs for this. Can I have the previous value in Django before saving?
Means new and old value.
Found this thread while searching for an answer to the same question. Why not do something like this? This way you can avoid touching database. And inbuilt
__init__
just a little extended. I think it's much more simple way than using signals.This has been answered elsewhere on Stack Overflow, but the correct way is to use something like this to track whether fields are dirty. Then you could use a signal to denote that something has changed that's of importance. (i.e. your field)
This method is to be added in a
Form
subclass. Its name isclean_FIELD_NAME
.cleaned_data
contains previous values. New value is stored inself.instance
.Alternatively,
validate()
method can be added to aforms.Field
subclass. See Django documentation.Instead of overriding the save method, wouldn't this be a good place to use signals? Intercept the save before commit, check the current value in the database, and either forward the save on, or reject it?
Now I'm not sure if the signal blocks the save request or if it happens asynch, so feel free to downvote this answer if a signal can not be used to prevent the save happening upon validation.
I'm against overriding inbuilt methods if there is another inbuilt tool that works just as well.
You can do this in an overridden
save
method. The thing to remember is that Django model instances aren't the actual database objects, they just get their values from there on load. So you can easily go back to the database before saving your current object to get the existing values.There is currently no good way of returning an error message to the user other than raising an exception. There is a Google Summer of Code project currently under way to enable 'model validation', but this will not be ready for a few months.
If you want to do something similar in the admin, the best way is to define a custom ModelForm with an overridden
clean()
method. However, this time since this is a form you already have access to the old values without hitting the db again. Another benefit is that you can return a form validation error to the user.