Django如何在模型created_at字段存储自定义日期时间
auto_now_add=True 生效时,字段会被自动设为不可编辑状态,且对象首次写入数据库时,无论是否手动传值,都会被强制覆盖为当前系统时间,直接赋值无法生效,可通过以下两种方案实现需求:
方案1:调整字段配置(推荐,兼顾默认自动填充+自定义传值)
将auto_now_add=True替换为default=timezone.now,既保留「未传值时自动填充创建时间」的默认行为,又开放字段的手动赋值权限,拿到用户传入的自定义时间后直接赋值即可正常存储。
首先修改模型定义:
from django.db import models from django.utils import timezone class YourModel(models.Model): # 移除auto_now_add配置,替换为default created_at = models.DateTimeField(default=timezone.now) # 其余字段保持原有定义即可
注意:
default=timezone.now不要加括号,需传入可调用对象,否则会在服务启动时固定时间值,导致默认填充时间错误。
修改完成后执行数据库迁移命令:
python manage.py makemigrations python manage.py migrate
后续创建对象时,传入自定义时间即可正常存入,未传值的场景仍会自动填充当前系统时间:
# custom_time为从前端获取、完成格式校验的带时区datetime对象 obj = YourModel.objects.create( created_at=custom_time, # 其余字段按业务逻辑传值 )
方案2:保留原有auto_now_add配置,创建后单独更新字段
如果因业务兼容需求不能修改现有字段配置,可先正常创建对象,再通过QuerySet的update()方法写入自定义时间——update()方法不会触发auto_now_add/auto_now的自动填充逻辑,可以直接写入指定值:
# 先正常创建对象,此时created_at会被自动填充为当前时间 obj = YourModel.objects.create( # 按业务逻辑传入其余字段值 ) # 单独更新created_at字段为自定义值 custom_time = # 完成校验的自定义datetime值 YourModel.objects.filter(pk=obj.pk).update(created_at=custom_time) # 重新从数据库拉取数据,拿到更新后的字段值 obj.refresh_from_db()
注意:不要尝试在调用
save()方法前直接给带auto_now_add=True的created_at字段赋值,该场景下字段值会被自动填充逻辑覆盖,无法生效。传入的自定义时间建议使用Django自带的timezone模块处理为带时区的datetime对象,避免和项目时区配置冲突导致时间存储错误。
内容的提问来源于stack exchange,提问作者SALMAN TAHIR
相关产品推荐
相关产品推荐

