Mam poniższy model db:
from datetime import datetime
class TermPayment(models.Model):
# I have excluded fields that are irrelevant to the question
date = models.DateTimeField(default=datetime.now(), blank=True)
Dodaję nową instancję, korzystając z poniższych:
tp = TermPayment.objects.create(**kwargs)
Mój problem: wszystkie rekordy w bazie danych mają tę samą wartość w polu daty, która jest datą pierwszej płatności. Po ponownym uruchomieniu serwera jeden rekord ma nową datę, a pozostałe rekordy są takie same jak pierwszy. Wygląda na to, że niektóre dane są buforowane, ale nie mogę znaleźć gdzie.
baza danych: mysql 5.1.25
django v1.1.1
default=datetime.now
- uwaga, bez wywoływania jak wnow()
Nie jest standardem dla DateTimeField, ale ... przydatna anycase.Odpowiedzi:
wygląda na to, że
datetime.now()
jest oceniane podczas definiowania modelu, a nie za każdym razem, gdy dodajesz rekord.Django ma funkcję umożliwiającą osiągnięcie tego, co próbujesz już zrobić:
lub
Różnica między drugim przykładem a tym, co aktualnie masz, to brak nawiasów. Przechodząc
datetime.now
bez nawiasów, przekazujesz aktualną funkcję, która będzie wywoływana przy każdym dodawaniu rekordu. Jeśli go zdaszdatetime.now()
, to właśnie oceniasz funkcję i przekazujesz jej wartość zwracaną.Więcej informacji jest dostępnych pod numerem referencyjnym modelu Django
źródło
expiry = models.DateTimeField(default=datetime.now + timedelta(days=30))
def now_plus_30(): return datetime.now() + timedelta(days = 30)
, a następnie użyćmodels.DateTimeField(default=now_plus_30)
default=lambda: datetime.now()+timedelta(days=30)
Zamiast używać
datetime.now
, powinieneś naprawdę używaćfrom django.utils.timezone import now
Odniesienie:
django.utils.timezone.now
więc wybierz coś takiego:
źródło
auto_now_add
porównasz je z polem oznaczonym znacznikiem czasu (który jest świadomy strefy czasowej), możesz uzyskać błędne obliczenia z powodu różnic w erżowych strefach czasowych.Z dokumentacji domyślnego pola modelu django:
Wartość domyślna dla pola. Może to być wartość lub obiekt na żądanie. Jeśli można wywołać, będzie wywoływany za każdym razem, gdy tworzony jest nowy obiekt.
Dlatego następujące powinny działać:
źródło
default
( django-chinese-docs-14.readthedocs.io/en/latest/ref/models/… )David miał właściwą odpowiedź. Nawias () powoduje, że wywoływana funkcja timezone.now () jest wywoływana przy każdej ocenie modelu. Jeśli usuniesz () z timezone.now () (lub datetime.now (), jeśli używasz naiwnego obiektu datetime), aby to zrobić:
Wtedy będzie działał zgodnie z oczekiwaniami:
Nowe obiekty otrzymają aktualną datę, kiedy zostaną utworzone, ale data nie zostanie zastąpiona za każdym razem, gdy zrobisz manage.py makemigrations / migrate.
Właśnie to spotkałem. Ogromne podziękowania dla Davida.
źródło
datetime.now()
Jest oceniana gdy klasa jest tworzona, gdy nowy rekord nie jest dodany do bazy danych.Aby osiągnąć to, co chcesz, zdefiniuj to pole jako:
W ten sposób
date
pole zostanie ustawione na bieżącą datę dla każdego nowego rekordu.źródło
Odpowiedź na to pytanie jest w rzeczywistości błędna.
Automatyczne wypełnianie wartości (auto_now / auto_now_add nie jest takie samo jak domyślne). Domyślną wartością będzie faktycznie to, co widzi użytkownik, jeśli jest to zupełnie nowy obiekt. Zazwyczaj robię to:
Upewnij się, że jeśli próbujesz reprezentować to na stronie administratora, umieść go na liście „tylko do odczytu” i odwołaj się do nazwy pola
Ponownie robię to, ponieważ mojej wartości domyślnej zwykle nie można edytować, a strony administracyjne ignorują elementy nieedytowalne, chyba że określono inaczej. Z pewnością jednak istnieje różnica między ustawieniem wartości domyślnej a wdrożeniem auto_add, który jest tutaj kluczowy. Przetestuj to!
źródło
datetime.now()
jest oceniany raz, gdy twoja instancja jest tworzona. Spróbuj usunąć nawias, aby funkcjadatetime.now
została zwrócona, a następnie obliczona. Miałem ten sam problem z ustawieniem wartości domyślnych dla moichDateTimeField
si zapisałem tutaj swoje rozwiązanie .źródło
Z odwołania do języka Python w części Definicje funkcji :
Na szczęście Django ma sposób na robienie tego, co chcesz, jeśli użyjesz
auto_now
argumentu dlaDateTimeField
:Zobacz dokumentację Django dla DateTimeField .
źródło
W Django 3.0
auto_now_add
wydaje się działaćauto_now
reg_date=models.DateField(auto_now=True,blank=True)
źródło