Django模型管理器查询集在感知日期时间过滤:在服务器重新启动之前不显示任何项目

时间:2013-08-28 10:23:27

标签: django datetime django-timezone

我有一个Django模型,它有一个publication_date和一个is_published字段。我为这个模型创建了一个管理器,它返回所有已发布的项目,这意味着:每个项目都有is_published = True和publication_date< = now。

class PublishedTextManager(models.Manager):
    """
        Filters out all unpublished items and items with a publication date in the future
    """
    def get_query_set(self):
        return super(PublishedTextManager, self).get_query_set() \
            .filter(is_published=True) \
            .filter(publication_date__lte=timezone.now())

使用此管理器的视图如下所示:

class NewsAndEventsOverView(ListView):

    model = News
    queryset = News.published.all().order_by('-publication_date')
    context_object_name = 'news_list'

    def get_context_data(self, **kwargs):
        # Initialize context and fill it with default data from NewsAndEventsOverView super class
        context = super(NewsAndEventsOverView, self).get_context_data(**kwargs)
        # Add view specific context
        context['latest_news_item'] = context['news_list'][0]
        today = timezone.now()
        yesterday = today - timedelta(days=1)
        context['upcoming_events_list'] = Event.published.filter(Q(date_end__gt=yesterday) | Q(date_start__gt=yesterday)).order_by('date_start')
        past_events_list = Event.published.filter(Q(date_end__lt=today) | Q(date_start__lt=today)).order_by('-date_start')
        old_news_list = context['news_list'][1:]
        context['old_news_and_events_list'] = sorted(chain(old_news_list, past_events_list), key=lambda x: x.publication_date, reverse=True)
        return context

相关的urls.py:

from .views import NewsAndEventsOverView

urlpatterns = patterns('',
    # Index page
    url(r'^$', NewsAndEventsOverView.as_view(), name="newsandevents_overview"),
)

当我默认添加新闻项时,它会将当前日期时间(timezone.now())作为发布日期接收,但是当我刷新页面时,它不会显示在前端,直到我重新启动服务器(使用django内置服务器atm)。 我在阿姆斯特丹时间(+2:00),当我向publication_date过滤器添加2个小时它工作正常,所以因为我是日期时间意识的新手,所以我猜我做错了什么。我已经尝试过timezone.now有和没有括号,但这没有什么区别。

2 个答案:

答案 0 :(得分:1)

我99%肯定你的模特上有类似的东西:

class News(models.Model):
    ....
    publication_date = models.DateTimeField(default=timezone.now())
    ....

实际上它为关键字参数'default'赋值,而不是将函数作为对象传递,每次创建新对象时都要调用它。你想传递一个函数'timezone.now'而不是这个函数的值,它将是'timezone.now()'

将其更改为:

class News(models.Model):
    ....
    publication_date = models.DateTimeField(default=timezone.now)
    ....

并且不要忘记在你想要给DateTimeField提供默认timezone.now值的代码的任何地方应用它

Cheets!如果您觉得这个答案有用,请不要忘记向上投票! ;)

答案 1 :(得分:1)

我遇到了类似的问题,这就是我的想法。当您使用queryset class属性时,查询将在每个请求上运行,但Manager中的timezone.now()调用会在每个请求上执行 not ,仅在类实例化时运行。请尝试使用get_queryset方法,这会强制它在每个请求上运行:

class NewsAndEventsOverView(ListView):

    model = News
    context_object_name = 'news_list'

    def get_queryset(self):
        return News.published.all().order_by('-publication_date')

    ...