Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Custom save method in model [closed]

Tags:

django

(Using Django 1.11.5)

Traditionally, I've always created a model like so:

class Animal(models.Model):
    is_hungry = models.BooleanField(default=True)

Then make changes like so:

animal = Animal()
animal.save()

animal.is_hungry = True
animal.save()

Recently, I saw a friend define a model with a custom save method:

class Animal(models.Model):
    is_hungry = models.BooleanField(default=True)

    def feed_animal(self):
        self.is_hungry = False
        self.save()

And calling this method appears to work as expected:

>>> from testapp.models import Animal
>>> a = Animal()
>>> a.save()
>>> a.is_hungry
True
>>>
>>> a.feed_animal()
>>> a.is_hungry
False

Are there any benefits/drawbacks in defining such a custom save method in the model definition? Is there any reason to prefer calling .save() on the object directly?

like image 664
Dirty Penguin Avatar asked Sep 12 '17 15:09

Dirty Penguin


2 Answers

There's no drawbacks but it might be not best practice to have implicit saves buried into model's methods. It'd be cleaner to define feed_animal method that just modifies the state of the model object and leave the saving to the view.py code:

# model.py
class Animal(models.Model):
    is_hungry = models.BooleanField(default=True)

    def feed_animal(self):
        # makes sense if ther's more to it than just setting the attribute
        self.is_hungry = False

# view.py
a = Animal()
a.feed_animal()
a.save()

The pattern with defining custom save methods is understood in Django as overriding save method of Model class in child class and make sense if you need to permamently change the object behaviour on save:

# model.py
class Animal(models.Model):
    is_hungry = models.BooleanField(default=True)

    def feed_animal(self):
        # makes sense if ther's more to it than just setting the attribute
        self.is_hungry = False

    # let say we need to save only well fed animals
    def save(self, *args, **kwargs):
        self.feed_animal()        
        super(Model, self).save(*args, **kwargs)
like image 195
Jarek.D Avatar answered Sep 24 '22 02:09

Jarek.D


This depends on your use cases.

In the example given above, if animal is fed, it will eventually end up the animal(object) being not hungry. Hence, in feed_animal function after setting up self.is_hungry(where self is the object itself), self.save is called to save the final state of object.

like image 26
kartikmaji Avatar answered Sep 22 '22 02:09

kartikmaji