You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 07:07:04