9

Let's say I have a class named Hero with a field named "name". Everytime a new Hero object is created, I want to append " is a hero". Can I use __init__ for that? Or is there a django-specific method I can override for that?

class Hero(modes.Model)
  name = models.CharField(max_length=100)
  def __init__(self, *args, **kwargs):
      name += " is a hero"
      super(Hero, self).__init__(*args, **kwargs)
3
  • 2
    This is almost never what you want. Describe your real problem. Commented Aug 5, 2012 at 23:27
  • @IgnacioVazquez-Abrams I have to update another Model which is based on aggregated input of my Hero class. Commented Aug 5, 2012 at 23:37
  • 1
    @Joey Use signals instead. Commented Aug 5, 2012 at 23:50

1 Answer 1

19

If by "every time a new Hero object is created" you mean "every time a Hero record is created in the database," then no, you don't want to do this in the __init__ method, since that is called any time a Hero object is created in Python, including when you are just getting an existing record from the database.

To do what you want, you can use Django's post_save signal, checking in the signal callback that the created keyword parameter is True and performing your "on creation" logic if so.

Alternatively, and more straightforward and natural in certain cases, you can override Hero's save() method as follows:

def save(self, *args, **kwargs):
    if not self.pk:  # object is being created, thus no primary key field yet
       self.name += " is a hero"
    super(Hero, self).save(*args, **kwargs)

Note that Djagno's bulk_create method will skip triggering either the post-save signal or calling save.

Sign up to request clarification or add additional context in comments.

3 Comments

As the docs explain, you should always include *args and **kwargs in the call to the parent class's save method, i.e. super(Hero, self).save(*args, **kwargs). The reason for this is to future-proof against changes (in Django, or your code) to the signature of the save() method.
As a warning for future readers, overriding save is not universally safe. Batch saves will not invoke overloaded save methods or call post_save and pre_save signals. I'm not sure if Django provides any way to customize on bulk update or creation, though it doesn't look like it, so you should be careful with how you do this and ensure that bulk saves don't take place if you defend on custom updating behavior.
Good point @Taywee -- I've added a note about this to the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.