设置会话时区

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