6

我有一个看起来像这样的模型:

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()并获取所有已发布的查询集Items

问题是 Django 似乎datetime.now()在服务器启动时在管理器中执行调用,然后缓存该值。因此,如果今天是 5 月 24 日,并且我创建了Item一个发布日期为 5 月 23 日的项目,并在 5 月 22 日启动了服务器,那么 5 月 23 日的项目将不会显示在ItemArchive视图中。一旦我重新启动 Apache,5 月 23 日的项目就会正确显示在视图中。

datetime.now()每次调用经理时,如何强制 Django 执行?

4

3 回答 3

13

我相信这是由您定义queryset = Item.objects.published()为类变量的视图引起的。此行将在ItemArchive最初导入您的类时执行一次。您应该将该行移到每次调用视图时都会执行的方法中。

于 2012-05-24T16:12:42.910 回答
4

不要使用queryset类变量,get_queryset而是覆盖。总的来说,我认为这queryset是一个红鲱鱼。如果您只是指定model,Django 会自动将查询集设置为self.model.objects.all(). 如果您需要任何过滤,100 次中有 99 次需要覆盖get_queryset以确保线程安全。请尝试以下操作。

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

    def get_queryset(self):
        return super(ItemArchive, self).get_queryset().published()
于 2012-05-24T16:50:11.200 回答
0

首先,只需使用models.DateTimeField(auto_now_add=True)

编辑:

二、使用get_queryset方法:

class ItemArchive(ArchiveIndexView):
    date_field = 'publish_date'

    def get_queryset(self):
        return Item.objects.published()
于 2012-05-24T16:21:27.457 回答