设置会话时区
Python 的 datetime.datetime
对象具有 tzinfo
属性,用于存储时区信息。设置属性时,对象被视为 Aware,当未设置属性时,它被视为 Naive。
为确保时区天真或有意识,你可以使用 .is_naive()
和 .is_aware()
如果你的 settings.py
文件中启用了 USE_TZ
,只要你的默认 TIME_ZONE
设置在 settings.py
中,datetime
就会附加时区信息
虽然此默认时区在某些情况下可能会很好,但可能还不够,尤其是在处理多个时区的用户时。为了实现这一点,必须使用中间件。
import pytz
from django.utils import timezone
# make sure you add `TimezoneMiddleware` appropriately in settings.py
class TimezoneMiddleware(object):
"""
Middleware to properly handle the users timezone
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# make sure they are authenticated so we know we have their tz info.
if request.user.is_authenticated():
# we are getting the users timezone that in this case is stored in
# a user's profile
tz_str = request.user.profile.timezone
timezone.activate(pytz.timezone(tz_str))
# otherwise deactivate and the default time zone will be used anyway
else:
timezone.deactivate()
response = self.get_response(request)
return response
还有一些新事物正在发生。要了解有关中间件及其功能的更多信息,请查看该部分文档 。在 __call__
中,我们正在处理时区数据的设置。首先,我们确保用户已通过身份验证,以确保我们为此用户提供时区数据。一旦我们知道了,我们就会使用 timezone.activate()
为用户会话激活时区。为了将时区字符串转换为 datetime 可用的时区,我们使用 pytz.timezone(str)
。
现在,当在模板中访问 datetime 对象时,它们将自动从数据库的 UTC
格式转换为用户所在的任何时区。只需访问 datetime 对象,并假设先前的中间件已设置,将设置其时区正常。
{{ my_datetime_value }}
如果你希望对用户的时区是否使用进行细粒度控制,请查看以下内容:
{% load tz %}
{% localtime on %}
{# this time will be respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
{% localtime off %}
{# this will not respect the users time zone #}
{{ your_date_time }}
{% endlocaltime %}
注意,此方法描述仅适用于 Django 1.10 及更高版本。要从 1.10 之前支持 django,请查看 MiddlewareMixin