时间戳失效主因是字段配置错误或绕过ORM的save()流程;需检查auto_now/auto_now_add设置,并确保用实例save()而非update()、bulk_create等;推荐手动管理时间戳以提升灵活性。

模型自动时间戳失效,通常是因为数据库字段未正确配置或 ORM 框架未启用自动更新逻辑。关键要确认两点:字段是否声明为自动生成(如 auto_now 或 auto_now_add),以及保存操作是否绕过了 ORM 的正常流程(比如用了 update()、原生 SQL 或 bulk_create)。
检查 Django 模型字段定义
Django 中常见的时间戳字段应使用:
-
created_at = models.DateTimeField(auto_now_add=True)—— 仅创建时写入,后续不可改 -
updated_at = models.DateTimeField(auto_now=True)—— 每次调用save()都刷新
⚠️ 注意:auto_now 和 auto_now_add 会强制覆盖传入值,且不支持在 Admin 或表单中手动编辑。若需灵活控制,建议改用 default=timezone.now + 重写 save() 方法。
避免绕过 save() 的更新方式
以下操作不会触发 auto_now:
MyModel.objects.filter(id=1).update(updated_at=timezone.now())MyModel.objects.bulk_create([...])- 原生 SQL 执行
UPDATE
✅ 正确做法:显式调用实例的 save(),例如:
obj = MyModel.objects.get(id=1) obj.field = "new value" obj.save() # 此时 updated_at 自动更新
自定义 save() 实现更可控的时间戳
当需要兼容手动赋值、API 更新或部分字段更新时,推荐手动管理:
- 移除
auto_now,改为default=timezone.now和blank=True, null=True - 在模型
save()中判断是否为更新操作:
from django.utils import timezone
<p>class MyModel(models.Model):
created_at = models.DateTimeField(default=timezone.now, blank=True)
updated_at = models.DateTimeField(blank=True, null=True)</p><pre class='brush:php;toolbar:false;'>def save(self, *args, **kwargs):
if self.pk: # 已存在,是更新
self.updated_at = timezone.now()
else: # 新建
self.created_at = timezone.now()
super().save(*args, **kwargs)</pre>注意时区与数据库默认值冲突
如果数据库(如 MySQL)字段设置了 DEFAULT CURRENT_TIMESTAMP,而 Django 又启用了 auto_now,可能引发冲突或被 DB 层覆盖。统一由 Django 管理更可控:
- 迁移时去掉数据库级默认值:
db_default=None(Django 4.2+) - 或确保数据库字段无默认,完全交由 Python 层处理

















