Django 1.11中DateTimeField存入UTC而非配置的Asia/Calcutta问题
解决Django 1.11中DateTimeField存储UTC而非IST的问题
嗨,我来帮你理清这个时间存储的问题!首先得明白为什么会出现这种情况:当你设置USE_TZ = True时,这是Django的默认设计行为——它会自动将所有DateTimeField的时间转换为UTC存储到数据库,目的是保证时间数据的全局一致性,不管你的服务器或客户端时区怎么变化。而你看到的IST时间,是Django在读取数据时自动转换回你设置的TIME_ZONE = 'Asia/Calcutta'后的结果。
不过如果你确实需要把IST时间直接存入数据库,这里有两种可行的方案:
方案一:关闭时区支持(简单但有局限性)
直接修改settings.py中的配置:
USE_TZ = False
这样Django会完全使用你设置的TIME_ZONE时区来存储和处理时间,不会再转换为UTC。但要注意,这个方案的弊端是失去了多时区支持,如果你的应用以后需要服务不同时区的用户,会带来很多麻烦,所以只推荐在单时区场景下使用。
方案二:自定义模型保存逻辑(推荐,保留时区支持)
如果你想保留USE_TZ = True的优势,同时让created_at和updated_at存储IST时间,可以去掉字段的auto_now_add和auto_now参数,手动在模型的save方法里设置时间:
from django.db import models from django.utils import timezone class YourModel(models.Model): # 去掉auto_now_add和auto_now参数 created_at = models.DateTimeField() updated_at = models.DateTimeField() def save(self, *args, **kwargs): # 获取当前的IST时间(因为TIME_ZONE已设为Asia/Calcutta,localtime()会返回IST) current_ist_time = timezone.localtime() # 新增记录时设置created_at if not self.pk: self.created_at = current_ist_time # 每次保存都更新updated_at self.updated_at = current_ist_time # 调用父类的save方法完成保存 super().save(*args, **kwargs)
这样既保留了Django的时区处理能力,又能让数据库中存储的是IST时间。
最后补充一句:其实Django推荐存储UTC时间是有道理的,它能避免时区转换带来的各种潜在问题。如果只是你在查看数据库时看到UTC觉得不习惯,但业务逻辑上没有问题,其实完全可以不用修改——因为Django在查询数据时,会自动把UTC时间转换为你设置的IST时间返回给你使用。
内容的提问来源于stack exchange,提问作者Rakmo
相关产品推荐
相关产品推荐

