Django创建对象时auto_now_add配置的created_at字段未自动填充问题
问题排查与修复方案
首先明确:你的模型字段定义逻辑本身是符合自动填充要求的
你在models.py里写的created_at = models.DateTimeField(auto_now_add=True),原生行为就是对象首次创建时自动写入当前时间,不需要在视图层手动传值,后续更新对象时也不会篡改这个创建时间,完全匹配你“创建时自动填值、无需手动传参”的核心需求。如果最终字段没有存储值,基本都是流程或者配置上的漏项导致的。
注意:如果你提到的“时间戳形式”是指存储整数类型的Unix时间戳(而非标准日期时间格式),那你当前选的字段类型不匹配——
DateTimeField会存储带时区的标准时间字符串。如果你要存储整数时间戳,需要把字段调整为BigIntegerField类型,配合默认值函数实现自动填充,示例:import time created_at = models.BigIntegerField( default=lambda: int(time.time()) )这种场景下不需要使用
auto_now_add参数,因为该参数仅支持DateTimeField类,用default指定取当前时间的函数即可实现创建时自动赋值。
常见问题原因与对应解决方式
- 没有完成数据库迁移同步
修改了模型定义之后,没有生成、执行对应的数据库迁移,导致实际的数据库表结构根本没有匹配上最新的模型字段定义。
对应操作:依次执行两条命令完成迁移
执行完成后,可以检查对应app的python manage.py makemigrations python manage.py migratemigrations目录下,最新的迁移文件里是否包含ConfigUser模型下created_at字段的定义,确认迁移真的生效了。 - 误把历史空数据当成新创建对象的取值
你在Admin里看到的空值记录,大概率是在加这个字段之前就创建的老数据,这些历史记录本身就没有created_at的存储值。新建一条测试数据核对新创建的对象是否有值,不要参考老记录的状态。
可以直接开Django shell验证最新创建对象的取值,排除Admin展示的干扰:
如果shell里能正常打印出时间值,说明字段自动填充的逻辑完全正常。from your_app.models import ConfigUser # 取最新创建的一条记录 latest_obj = ConfigUser.objects.order_by('-id').first() print(latest_obj.created_at) - 误判:Admin没展示字段而非字段没存值
带auto_now_add=True的字段,Django会自动设置editable=False,默认的Admin配置下,这类字段不会出现在对象详情页的表单里,很容易让你误以为值没存进去。
如果需要在Admin页面看到这个字段的值,需要在对应app的admin.py里调整注册配置,把字段设为只读展示:from django.contrib import admin from .models import ConfigUser @admin.register(ConfigUser) class ConfigUserAdmin(admin.ModelAdmin): # 把自动填充的字段加到只读展示列表,详情页就能看到值了 readonly_fields = ['created_at'] # 也可以在列表页直接展示这个字段,方便快速核对 list_display = ['ref', 'name', 'user', 'created_at'] - 多库连接错配排查
如果你配置了多数据库,要确认视图层创建对象时写入的库,和Admin站点读取的库是同一个,避免出现“数据写到了开发库、Admin看的是生产库”的错配情况。
内容的提问来源于stack exchange,提问作者Mike Delta
相关产品推荐
相关产品推荐

