Django已设置Asia/Kolkata时区却仍采用UTC的问题咨询
别着急,我们一步步来排查这个时区异常的问题。你已经设置了TIME_ZONE = 'Asia/Kolkata'和USE_TZ = False,但Django还是默认用UTC,大概率是下面几个常见原因:
1. 先确认服务器有没有重启!
这是最容易忽略的细节——修改settings.py后,必须完全重启Django开发服务器/生产服务器,不然新的配置根本不会生效。如果用的是runserver,直接Ctrl+C停掉再重新启动;如果是生产环境的uWSGI/Gunicorn,也要重启对应的服务。
2. 检查配置是否被其他地方覆盖
有时候项目里会有局部配置文件(比如local_settings.py)或者环境变量,偷偷改写了你的时区设置:
- 全局搜索项目里的
USE_TZ和TIME_ZONE,看有没有其他文件重新定义了这两个参数 - 检查环境变量,比如有没有用
os.environ.get('USE_TZ')这种方式覆盖配置,导致实际生效的是USE_TZ=True
你可以在Django shell里直接验证当前生效的配置:
from django.conf import settings print(settings.TIME_ZONE) # 正常应该输出Asia/Kolkata print(settings.USE_TZ) # 正常应该输出False
3. 验证时区是否被正确识别
有时候Asia/Kolkata这个时区标识可能因为pytz库版本过旧不被支持,你可以在Python shell里验证:
import pytz print('Asia/Kolkata' in pytz.all_timezones_set)
如果返回False,说明你的pytz版本太老了,执行pip install --upgrade pytz更新一下就行。
4. 检查新生成的数据时间
旧数据可能是之前用UTC存储的,所以显示还是UTC,你需要测试新创建的数据:
比如在shell里创建一个带时间字段的模型实例:
from datetime import datetime from your_app.models import YourModel # 创建一个实例,用当前时间 obj = YourModel.objects.create(created_at=datetime.now()) # 打印时间,正常应该是Asia/Kolkata的本地时间 print(obj.created_at)
如果新数据的时间是对的,那只是旧数据的问题,你可以批量迁移旧数据的时间(把UTC时间转成Asia/Kolkata时间);如果新数据还是UTC,那继续往下排查。
5. 视图和模板里的时间处理
- 视图代码:确保你没有用
datetime.utcnow()获取当前时间,应该用datetime.now()或者django.utils.timezone.now()(当USE_TZ=False时,后者和datetime.now()是等价的) - 模板渲染:检查模板里有没有用强制UTC的过滤器,比如
|timezone:"UTC",如果有的话删掉;另外如果开启了模板缓存,记得清一下缓存,不然旧的渲染结果还会显示。
6. 数据库时区设置(可选)
如果上面都没问题,那可能是数据库的时区在捣乱:
比如MySQL默认时区是UTC,当USE_TZ=False时,Django会把本地时间(Asia/Kolkata)直接存到数据库,但数据库会把这个时间当成UTC时间存储,导致显示的时候有偏差。这时候需要把数据库的时区改成Asia/Kolkata:
- MySQL的话,执行
SET GLOBAL time_zone = 'Asia/Kolkata';,并且在配置文件里永久设置 - PostgreSQL的话,修改
postgresql.conf里的timezone参数为Asia/Kolkata
按照上面的步骤排查,应该就能解决问题了!
内容的提问来源于stack exchange,提问作者venkateswar

