Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call a clean method before get_or_create saves to the database?

I've got a model in Django in which some data is frequently invalid. Usually I call a clean() method that I've written to deal with these situations, however, get_or_create() seems to call save() before I get a chance to call clean().

How can clean my data before get_or_create() attempts to write to the database?

Here's the relevant parts of my model:

class Article(models.Model):
    optional_attribute = models.CharField(max_length = 250)

    def clean(self):
        if not self.optional_attribute:
            self.optional_attribute = 'Default'
like image 986
Alex Avatar asked Jul 15 '15 17:07

Alex


2 Answers

It might be more appropriate to override the save method:

class Article(models.Model):
    optional_attribute = models.CharField(max_length = 250)

    def save(self, *args, **kwargs):
        if not self.optional_attribute:
            self.optional_attribute = 'Default'
        super(Article, self).save(*args, **kwargs)

Alternatively, you could use a pre_save signal handler:

from django.db.models.signals import pre_save

class Article(models.Model):
    optional_attribute = models.CharField(max_length = 250)

    @classmethod
    def pre_save_handler(cls, sender, instance, **kwargs):
        if not instance.optional_attribute:
            instance.optional_attribute = 'Default'

pre_save.connect(Article.pre_save_handler, sender=Article)

If you want to retain your clean method, you could simply use one of these techniques and call your clean method from within.

like image 68
dgel Avatar answered Nov 15 '22 04:11

dgel


The get_or_create method is just a shortcut. If you want to clean the object, you can write your code slightly more verbosely.

try:
    article = Article.objects.get(**params)
except Article.DoesNotExist:
    article = Article(**params) 
    article.full_clean()
    article.save()
like image 45
Alasdair Avatar answered Nov 15 '22 04:11

Alasdair