Explain Codes LogoExplain Codes Logo

Django auto_now and auto_now_add

python
datetime
django
timestamp
Alex KataevbyAlex Kataev·Feb 5, 2025
TLDR

The Django model options auto_now_add is used to record the very first timestamp when a record is created. While auto_now automatically updates the timestamp every time the record is saved or modified.

Example:

class MyModel(models.Model): initial_timestamp = models.DateTimeField(auto_now_add=True) latest_timestamp = models.DateTimeField(auto_now=True)

In this example, initial_timestamp is set when the object is first created, while latest_timestamp automatically updates each time the object is saved.

Custom save method: Take control of your timestamps

While the auto_now and auto_now_add options can be handy, they may not be the best for all situations due to their limitations. Fortunately, Django provides a way for you to have full control over these timestamps by defining a custom save() method.

Here's how:

from django.utils import timezone class MyModel(models.Model): initial_timestamp = models.DateTimeField(editable=False, null=False) latest_timestamp = models.DateTimeField(editable=False, null=False) def save(self, *args, **kwargs): if not self.id: # New record? It's party time! 🎉 self.initial_timestamp = timezone.now() # But the party doesn't stop! The time updates for every save 🔄 self.latest_timestamp = timezone.now() super(MyModel, self).save(*args, **kwargs)

With this method, you ensure that initial_timestamp is set once when the record is created, while latest_timestamp updates whenever the model instance is saved. Plus, both fields are read-only in Django admin due to editable=False, eliminating chances of meddling with the timestamps.

The auto_now and auto_now_add trap

Sure, auto_now and auto_now_add might seem like nice shortcuts, but don't be fooled! These two can bring trouble due to their database-dependent behavior and default settings. For instance, they both automatically set editable=False, keeping them invisible in Django's admin interface.

Instead of being lured by these shortcuts, opt for a default callable like django.utils.timezone.now. This function ensures the timestamp is dynamic and adjusts according to the server's timezone.

Step up your DateTime game

To avoid pitfalls and have more control over your DateTime fields in Django, here are some recommendations:

  • Consider creating a custom field type or use AutoDateTimeField for more flexibility.
  • Remember to set your DateTime fields to default=timezone.now without brackets to ensure that the default value isn't a static timestamp, but a dynamic callable.
  • Don't forget to check out Django bugs such as #7634 and #12785 to gain knowledge about the known issues associated with auto_now and auto_now_add.
  • Implement readonly_fields in Django Admin. This trick allows you to display your initial_timestamp and latest_timestamp without making them editable.

More power to the user!

Remember, Django is all about enabling you, the developer, to do your work in the easiest and most efficient way. This is evident in how it handles DateTime fields:

  • Django provides you with option, either to use auto_now and auto_now_add, or a custom save() method, and the choice is entirely up to you.
  • You need to ensure your DateTime fields are consistent with your needs and migrations. This means always double-checking your default callables and ensuring fields are set to NOT NULL where appropriate.