[Django] Timezones und Datum aus Formular

Django, Flask, Bottle, WSGI, CGI…
Antworten
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ich dachte ich fange mal an eine Anwendung so zu ändern, dass kein Datum mehr ohne Timezone verwendet wird, damit ich die doofen Einträge in den Logs los werden:
DateTimeField received a naive datetime (2013-01-01 00:00:00) while time zone support is active.
An sich kein Problem, meistens musste ich nur ein datetime.datetime.now() durch ein django.utils.timezone.now() ersetzen.

Die Anwendung hat einige Formulare, bei denen ein Datum gewählt werden kann um Daten aus der Datenbank zu selektieren (also von und bis):

Code: Alles auswählen

class ListSelectionForm(forms.Form):
    from_date = forms.DateField(label="Von", widget=DatePicker)
    till_date = forms.DateField(label="Bis", widget=DatePicker)
Die entsprechenden Daten hole ich mir im view über cleaned data:

Code: Alles auswählen

from_date = form.cleaned_data["from_date"]
till_date = form.cleaned_data["from_date"]
Da kommt dann aber ein datetime.date-Objekt heraus, und das scheint Django ebenfalls als "naive" anzusehen wenn ich die Daten verwende um damit auf der Datenbank zu selektieren. Die Dokumentation sagt:
When you enable time zone support, Django interprets datetimes entered in forms in the current time zone and returns aware datetime objects in cleaned_data.
Das scheint bei forms.DateField nicht der Fall zu sein.
Ich könnte jetzt natürlich das datetime.date-Objekt im View in ein datetime.datetime-objekt wandeln und dem eine Zeitzone verpassen - irgendwie habe ich aber das Gefühl etwas offensichtliches übersehen zu haben.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ich habe mir jetzt eine kleine Hilfe gebaut, die das datetime.date-Objekt bei Bedarf wandelt:

Code: Alles auswählen

from datetime import datetime
from datetime import date
from django.utils import timezone

def aware_date(naive_date):
    if isinstance(naive_date, date):
        aware_datetime = timezone.make_aware(
            datetime.combine(naive_date, datetime.min.time()), 
            timezone.get_default_timezone())
    elif isinstance(naive_date, datetime):
        if timezone.is_aware(naive_date):
            aware_datetime = naive_date
        else:
            aware_datetime = timezone.make_aware(naive_date, 
                timezone.get_default_timezone())
    else:
        raise TypeError(
            "naive_date must be datetime.date or datetime.datetime, NOT %s " % (
                type(naive_date)))
    return aware_datetime
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

get_default_timezone sollte wahrscheinlich get_current_timezone sein. datetime mit date vergleichen ist etwas schwierig; vlt solltest du deinen DB query auf __year,__month,__day umstellen oder so; das bessert sich mit 1.7 hoffentlich.
Antworten