Django
Strefy czasowe
Szukaj…
Wprowadzenie
Strefy czasowe są często kłopotliwe dla programistów. Django oferuje kilka wspaniałych narzędzi do Twojej dyspozycji, aby ułatwić obsługę stref czasowych.
Nawet jeśli projekt działa w jednej strefie czasowej, nadal dobrą praktyką jest przechowywanie danych jako UTC w bazie danych w celu obsługi przypadków oszczędności czasu. Jeśli operujesz na wielu strefach czasowych, konieczne jest przechowywanie danych czasu jako UTC.
Włącz obsługę strefy czasowej
Najpierw jest pierwszy, upewnij się, że USE_TZ = True
w pliku settings.py
. TIME_ZONE
także domyślną wartość strefy czasowej na TIME_ZONE
przykład TIME_ZONE='UTC'
. Zobacz pełną listę stref czasowych tutaj .
Jeśli USE_TZ
ma wartość False, TIME_ZONE
będzie strefą czasową, której Django użyje do przechowywania wszystkich czasów danych. Gdy USE_TZ
jest włączone, TIME_ZONE
jest domyślną strefą czasową, której Django użyje do wyświetlania czasów danych w szablonach i interpretacji czasów danych wprowadzonych w formularzach.
Przy włączonej obsłudze stref czasowych django będzie przechowywać dane datetime
w bazie danych jako strefa czasowa UTC
Ustawianie stref czasowych sesji
Obiekty datetime.datetime
Pythona mają atrybut tzinfo
który służy do przechowywania informacji o strefie czasowej. Kiedy atrybut jest ustawiony, obiekt jest uważany za Świadomy, a gdy atrybut nie jest ustawiony, jest uważany za Naiwny.
Aby upewnić się, że .is_naive()
czasowa jest naiwna lub świadoma, możesz użyć .is_naive()
i .is_aware()
Jeśli masz USE_TZ
włączone w Twojej settings.py
plik, datetime
będą miały odpowiednią strefę czasową z nim związane jak długo domyślny TIME_ZONE
jest ustawiony w settings.py
Chociaż ta domyślna strefa czasowa może być dobra w niektórych przypadkach, prawdopodobnie nie jest wystarczająca, szczególnie jeśli obsługujesz użytkowników w wielu strefach czasowych. Aby to osiągnąć, należy użyć oprogramowania pośredniego.
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
Dzieje się kilka nowych rzeczy. Aby dowiedzieć się więcej na temat oprogramowania pośredniego i jego funkcji, zapoznaj się z tą częścią dokumentacji . W __call__
zajmujemy się ustawieniem danych strefy czasowej. Najpierw upewniamy się, że użytkownik jest uwierzytelniony, aby upewnić się, że mamy dane strefy czasowej dla tego użytkownika. Kiedy wiemy, że tak, aktywujemy strefę czasową dla sesji użytkowników za pomocą timezone.activate()
. Aby przekonwertować ciąg strefy czasowej musimy na coś użytecznego przez datetime, używamy pytz.timezone(str)
.
Teraz, gdy obiekty datetime są dostępne w szablonach, zostaną one automatycznie przekonwertowane z formatu „UTC” bazy danych na dowolną strefę czasową, w której znajduje się użytkownik. Wystarczy wejść do obiektu datetime, a jego strefa czasowa zostanie ustawiona, zakładając, że skonfigurowano poprzednie oprogramowanie pośrednie prawidłowo.
{{ my_datetime_value }}
Jeśli chcesz precyzyjnie kontrolować, czy strefa czasowa użytkownika jest używana, spójrz na następujące kwestie:
{% 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 %}
Uwaga: opisana metoda działa tylko w Django 1.10 i późniejszych. Aby wesprzeć django sprzed 1.10, zajrzyj do MiddlewareMixin