Dla Django 1.1.
Mam to w moim models.py:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
Podczas aktualizacji wiersza otrzymuję:
[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error] return self.cursor.execute(query, args)
Odpowiednia część mojej bazy danych to:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
Czy to jest powód do niepokoju?
Pytanie poboczne: w moim narzędziu administracyjnym te dwa pola nie są wyświetlane. Czy to jest oczekiwane?
python
django
datetime
django-models
django-admin
Paul Tarjan
źródło
źródło
update()
metoda nie zadzwoni,save()
co oznacza, że nie możemodified
automatycznie zaktualizować polaOdpowiedzi:
Każde pole z
auto_now
ustawionym atrybutem również odziedziczyeditable=False
i dlatego nie pojawi się w panelu administracyjnym. W przeszłości mówiono o tym, aby argumentyauto_now
iauto_now_add
zniknęły, i chociaż nadal istnieją, uważam, że lepiej jest po prostu skorzystać z niestandardowejsave()
metody .Tak więc, aby to działało poprawnie, odradzam używanie
auto_now
lubauto_now_add
zamiast tego zdefiniowanie własnejsave()
metody, aby upewnić się, żecreated
jest aktualizowana tylko wtedy, gdyid
nie jest ustawiona (na przykład przy pierwszym tworzeniu elementu), i niech aktualizuje się zamodified
każdym razem, gdy element jest zapisany.Zrobiłem dokładnie to samo z innymi projektami, które napisałem przy użyciu Django, więc
save()
wyglądałoby to tak:Mam nadzieję że to pomoże!
Edytuj w odpowiedzi na komentarze:
Powód, dla którego po prostu trzymam się przeciążenia
save()
kontra poleganie na tych argumentach pola, jest dwojaki:django.utils.timezone.now()
vs.datetime.datetime.now()
, ponieważ wdatetime.datetime
zależności od tego zwróci obiekt rozpoznający TZ lub naiwnysettings.USE_TZ
.Aby odpowiedzieć na pytanie, dlaczego OP widział błąd, nie wiem dokładnie, ale wygląda na to, że
created
nawet nie jest w ogóle zaludniony, pomimo tegoauto_now_add=True
. Dla mnie wyróżnia się to jako błąd i podkreśla pozycję nr 1 na mojej małej liście powyżej:auto_now
iauto_now_add
jest w najlepszym razie niestabilna.źródło
save()
na każdym z moich modeli jest znacznie bardziej bolesne niż używanieauto_now
(ponieważ lubię mieć te pola na wszystkich moich modelach). Dlaczego te parametry nie działają?Chciałem jednak zaznaczyć, że opinia wyrażona w przyjętej odpowiedzi jest nieco przestarzała. Według najnowszych dyskusji (błędy django # 7634 i # 12785 ) auto_now i auto_now_add nigdzie się nie wybierają, a nawet jeśli przejdziesz do oryginalnej dyskusji , znajdziesz mocne argumenty przeciwko RY (jak w DRY) w niestandardowym zapisie metody
Zaproponowano lepsze rozwiązanie (niestandardowe typy pól), ale nie uzyskało ono wystarczającego tempa, aby przekształcić go w django. Możesz pisać własne w trzech wierszach (to sugestia Jacoba Kaplana-Mossa ).
źródło
Mówiąc o bocznym pytaniu: jeśli chcesz zobaczyć te pola w adminie (chociaż nie będziesz mógł ich edytować), możesz dodać
readonly_fields
do swojej klasy administratora.Cóż, dotyczy to tylko najnowszych wersji Django (uważam, 1.3 i wyżej)
źródło
XxAdmin
klasy. Przeczytałem go zbyt szybko i próbowałem dodać do moich zajęćAdminForm
lubModelForm
zajęć i nie miałem pojęcia, dlaczego nie renderują pól „tylko do odczytu”. BTW, czy istnieje możliwość posiadania prawdziwych pól „tylko do odczytu w formularzu?”Myślę, że najłatwiejszym (i być może najbardziej eleganckim) rozwiązaniem jest wykorzystanie faktu, że można ustawić
default
na żądanie. Aby obejść specjalną obsługę auto_now przez administratora, możesz po prostu zadeklarować pole w następujący sposób:Ważne jest, aby nie używać,
timezone.now()
ponieważ wartość domyślna nie byłaby aktualizowana (tj. Wartość domyślna jest ustawiana tylko po załadowaniu kodu). Jeśli często to robisz, możesz utworzyć niestandardowe pole. Jednak myślę, że to już dość SUCHE.źródło
makemigrations
interpretuje wartość domyślną jako czas uruchomieniamakemigrations
i dlatego uważa, że wartość domyślna uległa zmianie!default=timezone.now()
a nie co jest zalecane:default=timezine.now
(bez nawiasów)?Jeśli zmienisz klasę modelu w ten sposób:
To pole pojawi się na mojej stronie zmian administratora
źródło
python manage.py makemigrations
: KeyError: u'editable 'Na podstawie tego, co przeczytałem i moich dotychczasowych doświadczeń z Django, auto_now_add jest błędny. Zgadzam się z jthanizmem - zastępuj normalną metodę zapisu, jest czysta i wiesz, co się dzieje. Teraz, aby wyschło, utwórz abstrakcyjny model o nazwie TimeStamped:
A następnie, jeśli chcesz mieć model, który ma takie znaczniki czasu, po prostu podklasę:
Jeśli chcesz, aby pola były wyświetlane w panelu administratora, po prostu usuń tę
editable=False
opcjęźródło
timezone.now()
używasz tutaj? Zakładamdjango.utils.timezone.now()
, ale nie jestem pozytywny. Ponadto, dlaczego warto korzystaćtimezone.now()
zamiastdatetime.datetime.now()
?timezone.now()
jest to, żedatetime.datetime.now()
jest świadomy strefy czasowej, podczas gdy strefa czasowa jest naiwna. Możesz przeczytać o tym tutaj: docs.djangoproject.com/en/dev/topics/i18n/timezonesdefault=timezone.now
w polu konstruktora?update_fields
arg zostanie podany, a „last_modified” nie będzie na liście, dodałbym:if 'update_fields' in kwargs and 'last_modifed' not in kwargs['update_fields']: kwargs['update_fields'].append('last_modified')
Nie, Django automatycznie dodaje go podczas zapisywania modeli, więc jest to oczekiwane.
Ponieważ pola te są dodawane automatycznie, nie są wyświetlane.
Aby dodać do powyższego, jak powiedział synack, debata na liście mailingowej django ma na celu usunięcie tego, ponieważ „nie jest dobrze zaprojektowany” i „hack”
Oczywiście nie musisz pisać tego do każdego modelu. Możesz napisać do jednego modelu i odziedziczyć inne po nim.
Ale,
auto_add
i jakauto_now_add
tam są, wolałbym ich użyć, niż samemu pisać metodę.źródło
Potrzebowałem dziś czegoś podobnego w pracy. Domyślną wartością jest
timezone.now()
, ale można ją edytować zarówno w widokach administratora, jak i dziedziczących klasFormMixin
, więc dla utworzonego w moimmodels.py
kodzie poniższy kod spełniał te wymagania:Bo
DateTimeField
chyba usuwam.date()
z funkcji i zmieniamdatetime.date
nadatetime.datetime
lub lepiejtimezone.datetime
. Nie próbowałem tegoDateTime
, tylko zDate
.źródło
Możesz użyć
timezone.now()
dla utworzonych iauto_now
zmodyfikowanych:Jeśli używasz niestandardowego klucza podstawowego zamiast domyślnego
auto- increment int
,auto_now_add
spowoduje to błąd.Oto kod domyślnego DateTimeField.pre_save Django za pomocą
auto_now
iauto_now_add
:Nie jestem pewien, jaki
add
jest parametr . Mam nadzieję, że to coś takiego:źródło
Jeśli chodzi o wyświetlanie administratora, zobacz tę odpowiedź .
Uwaga:
auto_now
iauto_now_add
są ustawioneeditable=False
domyślnie, dlatego ma to zastosowanie.źródło
auto_now=True
nie działało dla mnie w Django 1.4.1, ale poniższy kod mnie uratował. Jest to data time świadoma strefy czasowej.źródło
Tutaj utworzyliśmy i zaktualizowaliśmy kolumny, które po utworzeniu będą miały znacznik czasu i gdy ktoś zmodyfikuje opinię.
auto_now_add ustawi czas utworzenia instancji, natomiast auto_now ustawi czas, gdy ktoś zmodyfikuje jego opinię.
źródło
Oto odpowiedź, jeśli korzystasz z południa i chcesz ustawić domyślnie datę dodania pola do bazy danych:
Wybierz opcję 2, a następnie: datetime.datetime.now ()
Wygląda tak:
źródło