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
相关产品推荐
相关产品推荐

