2

I'm trying to do a simple error reporting system within my Django classes, but I cannot get to save a new object (from another class) if I raise a ValidationError.

Here is an example of what I want to do:

from django.db import models
from django.core.exceptions import ValidationError

class History(models.Model):
    data = models.CharField(max_length=255)
    timestamp = models.DateTimeField(auto_now_add=True)

class PositiveNumber(models.Model):
    number = models.IntegerField()

    def save(self, *args, **kwargs):
        if self.number < 0:
            h = History(data="Error writing %d into 'Positive Numbers'" % (self.number,))
            h.save()         # Here is the problem: h doesn't get saved
            raise ValidationError('Positive numbers only')
        else:
            h = History(data="Saved %d into 'Positive Numbers'" % (self.number,))
            h.save()
        return super(PositiveNumber, self).save(*args, **kwargs)

The problem is that if I raise an exception, even if it is risen after I do the h.save(), h doesn't get saved.

This makes all the sense because Django is so intelligent that shouldn't let you commit to the database if there is an error, but I can't find anywhere in the documentation where I can override this to deal with this specific situation.

... or maybe I'm simply conceptually wrong and I have to deal with this elsewhere (I'm trying to do a robust system where others can write code for it so it should be fail-safe).

Alfredo Rius
  • 101
  • 5
  • Ideally, other models should be saved using a [`pre_save` signal](https://docs.djangoproject.com/en/1.8/ref/signals/#pre-save) – karthikr Jul 24 '15 at 20:08
  • Thanks karthikr, how do I do this? so far I've been trying [this](http://stackoverflow.com/questions/10904799/django-1-2-how-to-connect-pre-save-signal-to-class-method#answer-10904867) with not much success. – Alfredo Rius Jul 24 '15 at 20:53
  • There are lots of posts on stackoverflow showing how to use the signals. One of those should surely help. – karthikr Jul 24 '15 at 21:22
  • Don't really a solution, but you should consider doing any validation not in your `save()` method. The more-djangoish way would be the usage of a `Form` or `ModelForm` clean-method. See https://docs.djangoproject.com/en/1.8/ref/forms/validation/ for more details. – Mischback Jul 25 '15 at 14:08
  • Thanks @Mischback, but I am looking for a way that somebody else can write a form for the application and force the model to validate itself, just as if you try to write a text string into an integer field. – Alfredo Rius Jul 30 '15 at 19:05

0 Answers0