#36876 closed Bug (invalid)
Model timestamp fields get different values using auto_now
| Reported by: | Thomas Drevon | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 5.2 |
| Severity: | Normal | Keywords: | auto_now |
| Cc: | Thomas Drevon | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I have a BaseModel, which I use to set created_at and updated_at. Like so:
class BaseModel(models.Model):
id = models.CharField(primary_key=True, max_length=50, default=generate_nanoid, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
When a row is created in one of my tables, both created_at and udpated_at fields are set. Which is expected. What is not expected, is that the created_at field gets a slightly older value than the updated_at field. Typically:
created_at: 2026-01-22 08:53:38.479806+00
updated_at: 2026-01-22 08:53:38.479828+00
This is, in my opinion, a bug. Because create happens (I presume) in a single transaction. And also because these fields when, compared for similiarty, should reveal if the row has been updated at some later time.
As a workaround, one could override the model save method like so:
def save(self, *args, **kwargs):
"""Ensure created_at and updated_at are identical on creation"""
now = timezone.now()
if self._state.adding:
# On creation, set both to the same timestamp
if not self.created_at:
self.created_at = now
self.updated_at = self.created_at
else:
# On update, only touch updated_at
self.updated_at = now
super().save(*args, **kwargs)
This should probably get attention because it might be a symptom of inconsistent timestamp usage during create?
(My exact django version is v5.2.9)
Change History (3)
comment:1 by , 3 weeks ago
| Description: | modified (diff) |
|---|
comment:2 by , 3 weeks ago
| Keywords: | auto_now added |
|---|---|
| Resolution: | → invalid |
| Status: | new → closed |
comment:3 by , 2 weeks ago
Thanks for taking the time to answering this. I'm not sure I understand the statement "Nothing in the docs yokes this feature to transaction timestamps". But I appreaciate the tip about using TransactionNow from contrib.postres. I'll look into that.
Hi, thanks for the report.
Nothing in the docs yokes this feature to transaction timestamps. If you need transaction timestamps,
contrib.postgresships aTransactionNowexpression.There's also an accepted ticket to remove this feature entirely (#22995), so implementing model logic for this might be wise anyway.