У меня есть модель, которая выглядит следующим образом:Django, как представляется, кэширование datetime.now()
class Item(models.Model):
...
publish_date = models.DateTimeField(default=datetime.datetime.now)
...
и менеджер, который выглядит следующим образом:
from datetime import datetime
class ItemManager(Manager):
def published(self):
return self.get_query_set().filter(publish_date__lte=datetime.now()
и вид, который выглядит как это:
class ItemArchive(ArchiveIndexView):
queryset = Item.objects.published()
date_field = 'publish_date'
идея заключается в том, что я могу назвать Item.objects.published()
и получить QuerySet из всех опубликованных Items
.
Проблема заключается в том, что Django выполняет вызов datetime.now()
в менеджере при запуске сервера и затем кешировании этого значения. Так что если сегодня 24 мая, и я создал Item
с датой публикации от 23 мая и начал сервер 22 мая, этот 23 мая элемент не будет отображаться в представлении ItemArchive
. Как только я перезапускаю Apache, 23 мая элемент отображается правильно.
Как заставить Django выполнить команду datetime.now()
при каждом вызове менеджера?
Да. Или определите отдельный PublisherManager, который переопределяет 'get_query_set'. Это будет лениво, тогда как ваш «опубликованный» метод не будет. –
Это, безусловно, сработает. Лучшая техника будет зависеть от контекста. Если действительно имеет смысл иметь 'queryset' как переменную класса, то предложение Даниэля было бы лучше. Тем не менее, ваш код может быть более читабельным, если вы просто вызываете 'Item.objects.published()' везде, где вы сейчас используете 'queryset'. – dgel
Спасибо вам обоим! Мне потребовалось немного переделать, но оба решения имеют смысл. Я думаю, что dgel более уместен в моем контексте. – user1272534