Django pare a fi cache datetime.now ()

Am un model care arată astfel:

class Item(models.Model):
    ...
    publish_date = models.DateTimeField(default=datetime.datetime.now)
    ...

Și un manager care arată astfel:

from datetime import datetime

class ItemManager(Manager):
    def published(self):
        return self.get_query_set().filter(publish_date__lte=datetime.now()

Și o imagine care arată astfel:

class ItemArchive(ArchiveIndexView):
    queryset = Item.objects.published()
    date_field = 'publish_date'

Ideea fiind că pot apela Item.objects.published() și pentru a obține un queryset din toate Items publicate.

Problema este că Django pare să execute apelul datetime.now() în manager atunci când serverul este pornit și apoi să cacheze acea valoare. Deci, dacă astăzi este 24 mai și am creat un Item cu data publicării din 23 mai și am pornit serverul pe 22 mai, acel articol din 23 mai nu va apărea în ItemArchive . De îndată ce repornez Apache, articolul din 23 mai apare corect în vizualizare.

Cum pot forța Django să execute datetime.now() de fiecare dată când este apelat managerul?

0

3 răspunsuri

Nu utilizați variabila de clasă queryset și înlocuiți în schimb get_queryset . În general, cred că queryset este un pic de hering roșu. Dacă tocmai specificați model , Django va seta automat queryset-ul la self.model.objects.all() . Dacă aveți nevoie de filtrare, de 99 de ori din 100, va trebui să înlocuiți get_queryset pentru a fi sigură în legătură cu firul. Încercați în schimb următoarele.

class ItemArchive(ArchiveIndexView):
    model = Item
    date_field = 'publish_date'

    def get_queryset(self):
        return super(ItemArchive, self).get_queryset().published()
0
adăugat

Cred că acest lucru este cauzat de vizualizarea dvs. care definește queryset = Item.objects.published() ca variabilă de clasă. Această linie va fi executată o dată, când clasa ItemArchive este importată inițial. Ar trebui să mutați acea linie într-o metodă în care aceasta va fi executată de fiecare dată când este apelată o vizualizare.

0
adăugat
Mulțumesc amândoi! Mi-a trebuit puțin, dar ambele soluții au sens. Cred că dgel-ul este mai potrivit în contextul meu.
adăugat autor user1272534, sursa
Da. Sau, definiți un PublisherManager separat, care suprascrie get_query_set . Acest lucru va fi leneș, în timp ce metoda dvs. published nu este.
adăugat autor Daniel Roseman, sursa
Cu siguranță ar funcționa. Cea mai bună tehnică ar depinde de context. Dacă are sens să ai queryset ca variabilă de clasă, sugestia lui Daniel ar fi cea mai bună. Cu toate acestea, codul dvs. poate fi mai ușor de citit dacă apelați direct Item.objects.published() ori de câte ori utilizați în prezent queryset .
adăugat autor dgel, sursa

First, just use models.DateTimeField(auto_now_add=True)

Editat:

În al doilea rând, folosiți metoda get_queryset :

class ItemArchive(ArchiveIndexView):
    date_field = 'publish_date'

    def get_queryset(self):
        return Item.objects.published()
0
adăugat
Nu doresc să utilizez auto_now_add deoarece vreau să ofer utilizatorilor opțiunea de a edita data publicării. Suprascrierea get_queryset este ceea ce a sugerat dgel în răspunsul său. Cred că asta e soluția. Mulțumiri!
adăugat autor user1272534, sursa
Python România
Python România
100 participanți

Comunitatea pasionaților de Python din România.