Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a django model custom save() method, how should you identify a new object?

People also ask

What does save () do in Django?

To save changes to an object that's already in the database, use save() . This performs an UPDATE SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() .

How do I save changes in Django model?

save() method can be used to insert new record and update existing record and generally used for saving instance of single record(row in mysql) in database. update() is not used to insert records and can be used to update multiple records(rows in mysql) in database.

How object is stored in Django model?

A model in Django is supposed to correlate to a table in the database, so that each field in the model will actually be a field in the table for that model. To achieve what you're trying to do, you need to create a second model, which will be the object you want to store.

What is __ str __ In Django model?

The __str__() method is called whenever you call str() on an object. Django uses str(obj) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.


Alternative way to checking self.pk we can check self._state of the model

self._state.adding is True creating

self._state.adding is False updating

I got it from this page


Updated: With the clarification that self._state is not a private instance variable, but named that way to avoid conflicts, checking self._state.adding is now the preferable way to check.


self.pk is None:

returns True within a new Model object, unless the object has a UUIDField as its primary_key.

The corner case you might have to worry about is whether there are uniqueness constraints on fields other than the id (e.g., secondary unique indexes on other fields). In that case, you could still have a new record in hand, but be unable to save it.


Checking self.id assumes that id is the primary key for the model. A more generic way would be to use the pk shortcut.

is_new = self.pk is None


The check for self.pk == None is not sufficient to determine if the object is going to be inserted or updated in the database.

The Django O/RM features an especially nasty hack which is basically to check if there is something at the PK position and if so do an UPDATE, otherwise do an INSERT (this gets optimised to an INSERT if the PK is None).

The reason why it has to do this is because you are allowed to set the PK when an object is created. Although not common where you have a sequence column for the primary key, this doesn't hold for other types of primary key field.

If you really want to know you have to do what the O/RM does and look in the database.

Of course you have a specific case in your code and for that it is quite likely that self.pk == None tells you all you need to know, but it is not a general solution.


You could just connect to post_save signal which sends a "created" kwargs, if true, your object has been inserted.

http://docs.djangoproject.com/en/stable/ref/signals/#post-save


Check for self.id and the force_insert flag.

if not self.pk or kwargs.get('force_insert', False):
    self.created = True

# call save method.
super(self.__class__, self).save(*args, **kwargs)

#Do all your post save actions in the if block.
if getattr(self, 'created', False):
    # So something
    # Do something else

This is handy because your newly created object(self) has it pk value


I'm very late to this conversation, but I ran into a problem with the self.pk being populated when it has a default value associated with it.

The way I got around this is adding a date_created field to the model

date_created = models.DateTimeField(auto_now_add=True)

From here you can go

created = self.date_created is None