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

Django继承含auto_now_add字段的抽象基类时如何重写created日期

问题根因

Django 模型字段的 auto_now_add、auto_now 参数优先级高于实例化时传入的自定义值:只要开启这两个参数,无论你是否主动传入 created、modified 字段的值,新建/更新对象时都会被强制覆盖为当前时间,批量操作 bulk_create 也遵循该规则,这就是你传入的自定义时间不生效的原因。

解决方案

你可以通过调整字段配置的方式,既保留默认自动填充时间的能力,也支持自定义传值:

方案1:修改抽象基类(推荐,所有继承基类的模型都能生效)

将字段的 auto_now_add/auto_now 配置替换为 default 与自定义 save 逻辑即可:

from django.utils import timezone

class BaseModel(models.Model):
    # 替换auto_now_add为default,支持自定义传值,不传则默认用当前时间
    created = models.DateTimeField(_('created'), default=timezone.now)
    # 替换auto_now,后续通过save方法控制自动更新
    modified = models.DateTimeField(_('modified'), default=timezone.now)
    # ... 其他默认属性

    class Meta:
        abstract = True
    
    def save(self, *args, **kwargs):
        # 每次调用save方法时自动更新modified时间,和原auto_now行为保持一致
        self.modified = timezone.now()
        super().save(*args, **kwargs)

修改完成后你现有的业务代码不需要做任何调整:传入自定义created就用传入值,没传则自动填充当前时间,批量插入也能正常生效。

提示:如果你的Django项目开启了时区支持,建议将传入的时间戳转为带时区的时间对象,避免出现时区偏移问题。

方案2:仅修改Event子类(适合不能调整基类的场景)

如果无法修改BaseModel的定义,可以直接在Event子类中覆盖父类的created字段即可:

from django.utils import timezone

class Event(BaseModel):
    # 覆盖父类的created字段,去掉auto_now_add配置
    created = models.DateTimeField(_('created'), default=timezone.now)
    # ... Event的其他业务字段

内容的提问来源于stack exchange,提问作者Shawn Northrop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:06:04