10

If I have a model that has a UUID primary key and the the user may set the value on creation, is there any way to tell within the save method that the instance is new?

Previous techniques of checking the auto assigned fields: In a django model custom save() method, how should you identify a new object? do not work.

Community
  • 1
  • 1
Alex Rothberg
  • 10,243
  • 13
  • 60
  • 120

4 Answers4

3

Use self._state.adding. It defaults to True and gets set to False after saving the model instance or loading it from the DB.

You should also check the force_insert argument of save.

Note that this will not work if you attempt to copy an instance by changing its id and saving (a common shortcut). If you need to detect this, you could override the instance saving and loading to also store the pk on self._state, then compare the current pk with self._state.pk.

Jonathan Richards
  • 1,414
  • 1
  • 16
  • 20
0

In save(), self.pk is None with pk (uuid) dont work because it should has default = uuid.uuid4 and if you set it to default = None primarykey should has default attribute as valid uuid in DB, so let default = uuid.uuid4 in UUID field.

The esay way is to add field created_at:

created_at = models.DateTimeField(auto_now_add=True)

and in save() use :

if self.created_at is None:
  your code here
Delphi Coder
  • 1,723
  • 1
  • 14
  • 25
-1

save takes an optional parameter, force_insert. Passing that as True will force Django to do an INSERT. See the documentation.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
-1

You can use django-model-utils TimeStampedModel (you can also use django-extensions TimeStampedModel or make your own).

This provides each model a created and modified field. Then, compare the timedelta between the new instance's created and modified fields to an arbitrary time difference (this example uses 5 seconds). This allows you to identify if an instance is new:

def save(self, *args, **kwargs):
    super(<ModelName>, self).save(*args, **kwargs)

    if (self.modified - self.created).seconds < 5:
        <the instance is new>   
mcastle
  • 2,882
  • 3
  • 25
  • 43