Django用timezone.now和__range来查询天数范围?

时间:2012-12-28 22:00:12

标签: python django django-timezone

我正在使用PostgreSQL数据库(9.2.2)运行Django 1.4.3和Python 2.7。我有一个带有“last_view”字段的模型,该字段是用户上次查看记录的时间戳。在我的首页上,我想在上周显示十个查看次数最多的项目,所以在我的ListView中,我尝试将它用于我的查询集:

startdate = timezone.now() - datetime.timedelta(days=7)
enddate = timezone.now()
urlpatterns = patterns('',
    url(r'^$',
        ListView.as_view(
            queryset=Tag.objects.filter(last_view__range=([startdate, enddate])).order_by('-views')[:10],
            context_object_name='most_viewed_list',
            template_name='tags/index.html'),
        name='index'),

这在我第一次加载页面时有效。如果我单击任何记录并“查看”它们,则在数据库中更新last_view属性 - 但如果我重新加载页面,则此项目将从“最近查看”列表(由上述查询集形成)中消失。

我认为问题与此post有关,似乎timezone.now()的“enddate”在我启动服务器进程时受到限制。因此,当我在服务器运行后点击一个链接时,“当前时间”在未来与“now()”相比并超出范围(这就是我点击的记录在页面重新加载时消失的原因)。但是,如果我将内容更改为 now ,就像上面提到的那样,我在页面加载时出错:

startdate = timezone.now - datetime.timedelta(days=7)
enddate = timezone.now

不支持的操作数类型 - :'function'和'datetime.timedelta'

所以我无法创建我的startdate变量。我可以通过将我的查询集从_range更改为_gte来实现此功能,但是如果 now()在服务器进程启动而不是“当前时间”时实际上是时间戳,那么这似乎会突破。 “

queryset=Tag.objects.filter(last_view__gte=(timezone.now() - datetime.timedelta(days=7)).order_by('-views')[:10]

Django Tutorial on testing确实显示了使用现在对日期进行查询,但是它们没有显示如何从现在中减去天数或将其用于timedelta或日期范围...

有人可以解释如何从实际当前时间中取出时差,即使用现在而不是 now()?我还想更好地理解使用 now() now 的局限性。我找不到很好的文档,因为我可以通过timedelta()找到的所有示例都引用timezone.now()或datetime.now(),它可以工作(只是不是我想要的方式)。

谢谢!

1 个答案:

答案 0 :(得分:6)

子类ListView并覆盖get_queryset方法。通过计算startdate方法中的enddateget_querysettimezone.now()将是请求发出的时间,而不是最初加载urls.py时的时间。

class TagListView(ListView):
    def get_queryset(self):
        startdate = timezone.now() - datetime.timedelta(days=7)
        enddate = timezone.now()
        return Tag.objects.filter(last_view__range=[startdate, enddate]).order_by('-views')[:10]
    context_object_name='most_viewed_list'
    template_name='tags/index.html'

urlpatterns = patterns('',
    url(r'^$', TagListView.as_view(), name='index'),
)