Django’s auto_now and auto_now_add fields for auditing creation and modification timestamps
--
Adding fields to database schemas to audit the creation and modification is a common best practice, useful for any number of things, most commonly debugging and cache invalidation. The good news is, Django has field-types built for just this purpose!
auto_now and auto_now_add fields
As always, let’s start with the docs!
These fields are built into Django for expressly this purpose — auto_now
fields are updated to the current timestamp every time an object is saved and are therefore perfect for tracking when an object was last modified, while an auto_now_add
field is saved as the current timestamp when a row is first added to the database, and is therefore perfect for tracking when it was created.
It’s worth noting that that both fields are set on initial creation, whether they go through .save()
or bulk_create
- they may be a few milliseconds different, but will be effectively the same, but an auto_now_add
field won’t change again after it’s set.
Let’s dive in and talk through some quirks of these fields.
Read-only fields
Django’s DateField
definition includes this on init:
if auto_now or auto_now_add:
kwargs['editable'] = False
kwargs['blank'] = True
super(DateField, self).__init__(verbose_name, name, **kwargs)
This has some implications for both your Django admin set-up, as well as different-than-usual options, should you need to update these yourself.
Django Admin
Because both of these fields are read only, by default they won’t show up in your django admin view. If you try to explicitly include them via the fields
option, you’ll see an error that looks like this:
'created_at' cannot be specified for <ModelClass> model form as it is a non-editable field
If you want them to appear anyway, you can add them to readonly_fields
on a ModelAdmin
class, and they will be displayed on the form in a non-editable way. They can also be included in list_display
.