Newfoundland
Newfoundland

Reputation: 507

Preventing model save and raising a validation error from a pre_save signal

I am trying to prevent a model save if I have a page where the name is changed on an update. Ideally I would use the clean method and raise a validation error:

def clean (self):
    // if the name of the page has changed
    raise ValidationError({'name':'Sorry you cannot change this'})

However, I can't obtain the original name to compare it against the new instance name (can I?)

So I then tried using signals which enables me to grab the original name

@receiver(pre_save, sender=Page)
def prevent_save_if_name_same(sender,**kwargs):
    instance = kwargs.get('instance')
    old_model = sender.objects.get(pk=instance.id)
    if old_model.name == instance.name:
        // i would like to raise a validation error

However, I can't raise a ValidationError from within the signal which will propagate to the model save() method. When I try this I get the Django debug page - not the display of the error next to the name field as you would expect.

Any help much appreciated!

Upvotes: 5

Views: 4017

Answers (1)

neverwalkaloner
neverwalkaloner

Reputation: 47354

You can override __init__ method to save old_name value and then use this value in clean method:

class MyModel(models.Model):
    def __init__(self, *args, **kwargs):
        super(MyModel, self).__init__(*args, **kwargs)
        self._old_name = self.name

    def clean(self):
        if self._old_name != self.name:
            raise ValidationError({'name':'Sorry you cannot change this'})

Upvotes: 6

Related Questions