2012-11-05 15 views
12

Ten problem występował i wyłącza się już od kilku tygodni i różni się od innych, które pojawiły się w moim projekcie.Django default = timezone.now() zapisuje rekordy przy użyciu "starego" czasu.

Dwa używane modele mają znacznik czasu, który jest domyślnie ustawiony na timezone.now().

Jest to sekwencja, która podnosi flagi błędów: jeden


  • model jest tworzony w czasie 19:30

  • model jest tworzony w dwóch czas 10:00 PM, ale w bazie danych MySQL jest ona przechowywana jako godzina 19:30!

Każdy model, który jest tworzony ma swój znacznik czasu zapisaną pod 7:30 PM, a nie rzeczywisty czas, dopóki pewna czas mija. Następnie nowy czas jest ustawiony i wszystkie poniższe modele mieć ten nowy czas ... Bizzare


jakieś dodatkowe szczegóły, które mogą pomóc w odkrywaniu problem:

Mam kilka metod, które ja użyj do usunięcia stref czasowych z ich tzinfo i zastąp je UTC.

To dlatego, że wykonuję obliczenia timezone.now() - creationTime, aby utworzyć: "model został opublikowany to dawno temu" w projekcie . Jednak to naprawdę nie powinno być przyczyną problemu.

Nie sądzę, że użycie datetime.datetime.now() będzie miało również znaczenie.

W każdym razie, dziękuję za pomoc!

+1

Założę się, że problem "został naprawiony" dla pierwszego rekordu * po * wznowieniu procesu serwera (i być może tylko/wszystkie nowe rekordy wstawiono w tej samej minucie restart serwera). Pokaż kod, który używa/ustawia/ustanawia tę domyślną wartość. Podejrzewam, że jest on oceniany * raz * (gdy tworzony jest pierwszy rekord) i nie jest aktualizowany dla kolejnych rekordów. –

+0

Twoje prognozy są poprawne! Co sprawia, że ​​tak myślisz i dlaczego tak się dzieje? –

Odpowiedz

44

Właśnie wpadłem na ten ostatni tydzień dla pola, które miało default=date.today(). Jeśli usuniesz nawiasy (w tym przypadku spróbuj default=timezone.now), to przekażesz wywołanie modelowi i będzie on wywoływany za każdym razem, gdy zostanie zapisana nowa instancja. W nawiasach jest on wywoływany tylko raz, gdy ładuje się models.py.

+1

To jest bardzo fajne, dzięki za odpowiedź. Przełęcz funkcji jest raczej myląca, ponieważ od chwili rozpoczęcia z django jako amateaur, każdy przewodnik, który przeczytałem, a nawet wszystkie książki miały datetime.datetime.teraz() lub timezone.now() ustawione jako domyślne dla znaczników czasu, jest to po prostu coś, co zrobiłem automatycznie dla wszystkich moich znaczników czasu! –

+0

Przypuszczam, że wykonanie tego w niewłaściwy sposób mogłoby zadziałać, jeśli wdrożyłeś tylko aplikacje Django ze staromodnym CGI; i oczywiście musisz przetestować przez kilka godzin lub dni, aby zauważyć, że te sygnatury czasowe się nie aktualizują ... Ale jeśli jest to powszechna rada, nie daje mi to zaufania do testów tych autorów. : -/ –

+3

Nie jestem pewien, jakie przykłady mogłyby kiedykolwiek sugerować wywołanie 'datetime.now()'. Do czasu, gdy funkcja field odbiera ten argument, jest to po prostu obiekt datetime. –

7

Wystarczy ustawić parametr auto_now_add w ten sposób.

timestamp = models.DateTimeField(auto_now_add=True) 

Aktualizacja:

Proszę nie używać auto_now_add. Nie jest to zalecany sposób, zamiast tego:

from django.utils import timezone 

timestamp = models.DateTimeField(default=timezone.now) 
+1

Nie jest to już preferowana metoda osiągnięcia tego. [Przestarzałe] (https://code.djangoproject.com/ticket/22995) – davelupt