Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Overriding the Model.create() method?

The Django docs only list examples for overriding save() and delete(). However, I'd like to define some extra processing for my models only when they are created. For anyone familiar with Rails, it would be the equivalent to creating a :before_create filter. Is this possible?

like image 532
ground5hark Avatar asked Feb 21 '10 23:02

ground5hark


People also ask

What is create method in Django?

To answer the question literally, the create method in a model's manager is a standard way to create new objects in Django.

How do you override a save model?

save() method from its parent class is to be overridden so we use super keyword. slugify is a function that converts any string into a slug. so we are converting the title to form a slug basically.

What is Save () in Django?

save() , django will save the current object state to record. So if some changes happens between get() and save() by some other process, then those changes will be lost.


2 Answers

Overriding __init__() would cause code to be executed whenever the python representation of object is instantiated. I don't know rails, but a :before_created filter sounds to me like it's code to be executed when the object is created in the database. If you want to execute code when a new object is created in the database, you should override save(), checking if the object has a pk attribute or not. The code would look something like this:

def save(self, *args, **kwargs):     if not self.pk:         # This code only happens if the objects is         # not in the database yet. Otherwise it would         # have pk     super(MyModel, self).save(*args, **kwargs) 
like image 129
Zach Avatar answered Sep 30 '22 03:09

Zach


This is old, has an accepted answer that works (Zach's), and a more idiomatic one too (Michael Bylstra's), but since it's still the first result on Google most people see, I think we need a more best-practices modern-django style answer here:

from django.db.models.signals import post_save  class MyModel(models.Model):     # ...     @classmethod     def post_create(cls, sender, instance, created, *args, **kwargs):         if not created:             return         # ...what needs to happen on create  post_save.connect(MyModel.post_create, sender=MyModel) 

The point is this:

  1. use signals (read more here in the official docs)
  2. use a method for nice namespacing (if it makes sense) ...and I marked it as @classmethod instead of @staticmethod because most likely you'll end up needing to refer static class members in the code

Even cleaner would be if core Django would have an actual post_create signal. (Imho if you need to pass a boolean arg to change behavior of a method, that should be 2 methods.)

like image 25
NeuronQ Avatar answered Sep 30 '22 02:09

NeuronQ