Django Models问题:auto_now字段首次创建时与auto_now_add时间一致
Django模型创建时updated_at自动填充的问题解决
问题原因
Django中auto_now=True的字段特性是:只要调用模型的save()方法,就会自动将字段值设为当前时间。而创建新记录时必然会执行一次save(),所以updated_at会和created_at被同时赋值为当前时间,导致两者时间一致。
解决方案
方案1:重写模型save方法(推荐)
修改updated_at的字段定义,去掉auto_now=True,然后在save方法里控制只有更新操作时才设置该字段:
from django.db import models from django.utils import timezone class BaseModel(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(null=True, blank=True) class Meta: abstract = True # 做成抽象基类,方便其他模型继承 def save(self, *args, **kwargs): # 仅当记录已存在(更新操作)时,更新updated_at if self.pk: self.updated_at = timezone.now() super().save(*args, **kwargs) # 其他模型继承这个基类即可 class YourModel(BaseModel): # 你的模型字段 title = models.CharField(max_length=100)
这样首次创建记录时,updated_at会保持为null,后续每次修改保存时,都会自动更新为当前时间。如果不想让字段为null,可以给个初始默认值,但首次创建时不会覆盖它。
方案2:使用信号统一处理
如果不想每个模型都重写save方法,可以用Django的post_save信号全局处理:
from django.db.models.signals import post_save from django.dispatch import receiver from django.utils import timezone @receiver(post_save) def update_updated_at(sender, instance, created, **kwargs): # 只处理有updated_at字段的模型,且仅在更新时执行 if hasattr(instance, 'updated_at') and not created: instance.updated_at = timezone.now() # 使用update_fields避免递归触发save instance.save(update_fields=['updated_at'])
记得在你的app的apps.py中注册这个信号,或者在models.py末尾导入信号文件。
方案3:前端展示时做判断
如果不想修改后端逻辑,也可以在前端模板里判断,当两个时间一致时不显示更新时间:
<div class="record-info"> <p>创建时间:{{ object.created_at|date:"Y-m-d H:i:s" }}</p> {% if object.updated_at and object.updated_at != object.created_at %} <p>更新时间:{{ object.updated_at|date:"Y-m-d H:i:s" }}</p> {% endif %} </div>
内容的提问来源于stack exchange,提问作者Asim Ejaz
相关产品推荐
相关产品推荐

