Django auto_now and auto_now_add
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Django gives DateTimeField two convenience options for automatic timestamps: auto_now and auto_now_add. They look similar, but they solve different problems, and using the wrong one can make a model harder to work with later.
What auto_now_add Does
auto_now_add=True sets the field once, when the object is first created. It is the usual choice for a created_at column because that value should represent the original insertion time.
When a new Article is saved for the first time, Django fills created_at automatically. Later saves do not change it.
What auto_now Does
auto_now=True updates the field every time Django saves the model instance. That makes it a good fit for an updated_at field.
With this model, updated_at changes on every save(), while created_at stays fixed.
Seeing the Difference in Practice
The following shell session shows the typical behavior:
This distinction is the core rule: auto_now_add is for creation time, and auto_now is for last-modified time.
When default=timezone.now Is Better
These options are convenient, but they are not always flexible enough. If you want a timestamp that starts with the current time yet can still be edited later, use default=timezone.now instead.
This gives the field an initial value without locking you into Django's automatic overwrite behavior. That matters for imported data, backfills, or admin workflows where a human needs to adjust the timestamp.
Important Behavior in Forms and Queries
Fields using auto_now and auto_now_add are not meant for user entry. In practice, Django treats them as managed fields, so they are excluded from normal form editing behavior.
Another important detail is that bulk updates do not call save() on each model instance. If you do this:
Django sends a direct SQL update, so auto_now does not fire automatically. If you need a timestamp change during bulk operations, include it explicitly.
That behavior surprises many developers because instance saves and queryset updates do not go through the same path.
Time Zone Considerations
If USE_TZ is enabled, Django stores aware datetimes and converts them according to project settings. That is usually what you want. The key point is to stay consistent across your application so timestamp comparisons behave correctly.
For timestamps managed by Django, avoid mixing naive manual datetimes with timezone-aware values. Use timezone.now() when you need to set a value yourself.
Common Pitfalls
Using auto_now_add for an updated_at field is wrong because the value will never change after creation.
Using auto_now for a field that users should edit later is frustrating because Django overwrites it on every save.
Assuming QuerySet.update() triggers auto_now is a common mistake. It does not call model save().
Trying to import historical records with auto_now_add can be awkward because Django wants to manage the field automatically. Use a normal field with default=timezone.now when manual control matters.
Ignoring time zone settings can produce confusing comparisons and display bugs in multi-region systems.
Summary
- '
auto_now_addsets a timestamp once at creation time.' - '
auto_nowrefreshes a timestamp on every model save.' - Use them for
created_atandupdated_atrespectively. - Choose
default=timezone.nowwhen you need an editable initial timestamp. - Remember that bulk queryset updates bypass the automatic
save()behavior.

