Buscar..


Introducción

Las zonas horarias son a menudo una molestia para los desarrolladores. Django ofrece algunas excelentes utilidades a su disposición para facilitar el trabajo con las zonas horarias.

Incluso si su proyecto está operando en una sola zona horaria, sigue siendo una buena práctica almacenar datos como UTC en su base de datos para manejar los casos de ahorro de luz diurna. Si está operando en múltiples zonas horarias, almacenar datos de tiempo como UTC es una necesidad.

Habilitar soporte de zona horaria

Primero es primero, asegúrese de que USE_TZ = True en su archivo settings.py . También establezca un valor de zona horaria predeterminado en TIME_ZONE , como TIME_ZONE='UTC' . Vea una lista completa de zonas horarias aquí .

Si USE_TZ es Falso, TIME_ZONE será la zona horaria que Django usará para almacenar todas las fechas de los datos. Cuando USE_TZ está habilitado, TIME_ZONE es la zona horaria predeterminada que Django usará para mostrar los tiempos de las fechas en las plantillas e interpretar los tiempos de los datos ingresados ​​en los formularios.

Con el soporte de zona horaria habilitado, django almacenará los datos de datetime y datetime en la base de datos como la zona horaria UTC

Configuración de zonas horarias de sesión

Los objetos datetime.datetime de Python tienen un atributo tzinfo que se utiliza para almacenar información de zona horaria. Cuando se establece el atributo, el objeto se considera consciente, cuando el atributo no se establece, se considera un ingenuo.

Para asegurarse de que una zona horaria sea ingenua o consciente, puede usar .is_naive() y .is_aware()

Si tiene USE_TZ habilitado en su archivo settings.py , una datetime y datetime tendrá información de zona horaria adjunta siempre que su TIME_ZONE predeterminado esté configurado en settings.py

Si bien esta zona horaria predeterminada puede ser buena en algunos casos, es probable que no sea suficiente, especialmente si está manejando usuarios en múltiples zonas horarias. Para lograr esto, se debe utilizar middleware.

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

Hay algunas cosas nuevas que están sucediendo. Para obtener más información sobre el middleware y lo que hace, consulte esa parte de la documentación . En __call__ estamos manejando la configuración de los datos de la zona horaria. Al principio, nos aseguramos de que el usuario esté autenticado, para asegurarnos de que tenemos datos de la zona horaria para este usuario. Una vez que sabemos que lo hacemos, activamos la zona horaria para la sesión de los usuarios utilizando timezone.activate() . Para convertir la cadena de zona horaria que tenemos a algo utilizable por datetime, usamos pytz.timezone(str) .

Ahora, cuando se accede a los objetos de fecha y hora en plantillas, se convertirán automáticamente del formato 'UTC' de la base de datos a cualquier zona horaria en la que se encuentre el usuario. Simplemente acceda al objeto de fecha y hora y se establecerá su zona horaria, asumiendo que el middleware anterior esté configurado correctamente.

{{ my_datetime_value }}

Si desea un control detallado sobre si se usa la zona horaria del usuario, mire lo siguiente:

{% 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 %}

Tenga en cuenta que este método descrito solo funciona en Django 1.10 y en. Para admitir django desde antes de 1.10, busque en MiddlewareMixin



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow