Django
Tidszoner
Sök…
Introduktion
Tidzoner är ofta krångel för utvecklare. Django erbjuder några fantastiska verktyg till ditt förfogande för att göra tidszoner lätt att arbeta med.
Även om ditt projekt fungerar i en enda tidszon är det fortfarande god praxis att lagra data som UTC i din databas för att hantera fall av sommartid. Om du använder flera tidszoner är det ett måste att lagra tidsdata som UTC.
Aktivera stöd för tidszon
Först är först, se till att USE_TZ = True
i filen settings.py
. Ställ också in ett standardtidszonvärde till TIME_ZONE
som TIME_ZONE='UTC'
. Visa en komplett lista med tidszoner här .
Om USE_TZ
är falskt kommer TIME_ZONE
att vara den tidszon som Django kommer att använda för att lagra alla tidpunkter. När USE_TZ
är aktiverat är TIME_ZONE
den standardtidszon som Django kommer att använda för att visa datatider i mallar och för att tolka datatider som anges i formulär.
Med tidszonstöd aktiverat kommer django att lagra datetime
i databasen som tidszon UTC
Ställa in sessionens tidszoner
Pythons datetime.datetime
objekt har ett tzinfo
attribut som används för att lagra information om tidszon. När attributet är inställt anses objektet vara medvetet, när attributet inte är inställt betraktas det som en naiv.
För att säkerställa att en tidszon är naiv eller medveten kan du använda .is_naive()
och .is_aware()
Om du har USE_TZ
aktiverat i filen settings.py
, kommer en datetime
att ha datetime
kopplad till den så länge din standard TIME_ZONE
är inställd i settings.py
Även om denna standardtidszon kan vara bra i vissa fall är det troligtvis inte tillräckligt, särskilt om du hanterar användare i flera tidszoner. För att uppnå detta måste mellanvaror användas.
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
Det finns några nya saker på gång. För att lära dig mer om middleware och vad den gör, kolla in den delen av dokumentationen . I __call__
vi inställningen av tidszondata. Först ser vi till att användaren är autentiserad, för att se till att vi har tidszoninformation för den här användaren. När vi vet att vi gör det, aktiverar vi tidszonen för användarsessionen med hjälp av timezone.activate()
. För att konvertera tidszonssträngen till något användbart från datetime använder vi pytz.timezone(str)
.
När datetime-objekt nu öppnas i mallar kommer de automatiskt att konverteras från "UTC" -formatet i databasen till vilken tidszon användaren befinner sig i. Bara åtkomst till datetime-objektet och dess tidszon kommer att ställas in under förutsättning att den tidigare mellanprogrammet är inställt ordentligt.
{{ my_datetime_value }}
Om du önskar en finkornig kontroll av om användarens tidszon används ska du titta på följande:
{% 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 %}
Observera att den här metoden som beskrivs endast fungerar i Django 1.10 och senare. För att stödja django från före 1.10 titta in i MiddlewareMixin