21

While overriding the specific model's save() method, Is it possible determine whether it's a new record or an update?

andilabs
  • 22,159
  • 14
  • 114
  • 151
Siva Arunachalam
  • 7,582
  • 15
  • 79
  • 132

2 Answers2

58

If self.pk is None it is a new record.

def save(self):
    if self.pk is None:
        self.created = datetime.today()
    self.modified = datetime.today()
    super(ProjectCost, self).save()

This topic has been discussed also here

Community
  • 1
  • 1
Thomas Kremmel
  • 14,575
  • 26
  • 108
  • 177
  • 3
    Please let me note here, that Django has built-in keywords for recording the object creation and modification dates: you can use the `auto_now` and `auto_now_add` parameters of `DateTimeField` in the model definition. – gklka Nov 15 '13 at 17:08
  • 18
    pk is not `None` if you are using UUIDField for pk - even if the instance is new. – user3467349 Jun 16 '16 at 18:53
  • 1
    This will NOT work when you are saving a multi-table Child Model Class. The parent instance is created first before saving the child instance. And by default, the pk for the child instance is attained from the parent instance's pk. So, it will never be `None`. – kiiru May 02 '18 at 04:04
7

The preferred solution in modern Django is to check self._state.adding

Unfortunately this is not currently documented, but there is an open task to do so https://code.djangoproject.com/ticket/31502

Gordon Wrigley
  • 11,015
  • 10
  • 48
  • 62
  • I just posted a comment about this in another topic (from 2017), but this one is much more current, so I'll ask here as well. What's the definitive stance on using "private" properties/methods. I know Python doesn't actually have private properties, that the "_" is merely an accepted convention. But I'm curious to know if it's ok to rely on ```_state```. – ExTexan Jul 06 '20 at 02:23
  • 2
    @ExTexan the whole underscore private thing is a convention. You could choose to have underscores mean something else, or nothing at all. With regard to Django they have stated that _state and _meta are public API's that you are free to use. They have names starting underscore to prevent them from clashing with user fields. Not because they are private. – Gordon Wrigley Jul 06 '20 at 08:02