Django 查询今天的所有项目

Django query for all items from today

我想查询并获取今天创建的所有页面。这是我的模型:

class Page(models.Model):
    user = models.ForeignKey('User', related_name='pages', blank=True, null=True)
    title = models.CharField(max_length=2000, default='', blank=True)
    date_created = models.DateTimeField(default=datetime.datetime.now)

我正在尝试这样查询:

todays_pages = Page.objects.filter(date_created = datetime.date.today())

除了它不起作用,除非我将字段更改为日期字段而不是日期时间字段。

您可以根据时间筛选对象。我会这样做的方式是这样的......

today = datetime.date.today()
todays_pages = Page.objects.filter(date_created__range=[today,])

我没有专门尝试过这段代码,但这是我对如何获取所有具有当前日历日的帖子的最佳猜测。

你可以这样试试:

todays_pages = Page.objects.filter(date_created__gte = datetime.date.now().replace(hour=0,minute=0,second=0))

datetime.datetime.now() 不知道时区。您可能需要使用 django.utils.timezone 进行转换。

这看起来应该很容易,但实际上这是一个不平凡的问题,主要是由于时区。您的 DateTimeField 存储了一个特定的时间点。该时间点发生的日期在不同的时区可能不同 - 完全相同的时间点可能是柏林的星期三早上,但旧金山的星期二晚上。

给定您要查询的日期和时区,策略是这样的:

1) 为 "start of that day in that timezone" 构造一个日期时间,为 "end of that day in that timezone".

构造一个日期时间

2) 查询开始日期和结束日期之间有 date_created 的页面。

在我最近写的一些代码中,我有一个 combine 函数,用于将日期、时间和时区组合成日期时间:

from django.utils import timezone
import pytz

def combine(adate, atime, tz=None, is_dst=None):
    """Turn a date and a time into a datetime in given timezone (or default).

    The ``is_dst`` argument controls the handling of ambiguous datetimes
    (e.g. during fall DST changeover), and nonexistent datetimes (e.g. during
    spring DST changeover). If it is ``None`` (the default), these cases will
    return ``None`` instead of a datetime. If it is ``True``, these cases will
    be resolved by always assuming DST, and if ``False`` by assuming no-DST.

    """
    tz = tz or timezone.get_current_timezone()
    naive = dt(adate.year, adate.month, adate.day, atime.hour, atime.minute)
    try:
        return tz.normalize(tz.localize(naive, is_dst=is_dst))
    except pytz.InvalidTimeError:
        return None

那么您的查询如下所示:

def get_pages_created_on_date(for_date):
    start = combine(for_date, time(0))
    end = combine(for_date + datetime.timedelta(days=1), time(0))
    return Page.objects.filter(date_created__gte=start, date_created__lt=end)

该版本只使用当前激活的时区(这可能是您的 Django 设置文件中配置的时区,除非您已经完成一些额外的工作来为当前请求的用户激活本地时区)。

我不知道 DST 转换发生在午夜的任何时区,这应该可以使此代码免受 DST 转换问题的影响。但是如果有这样一个时区,并且您可能需要处理其中的日期时间,那么您的查询函数将需要将 is_dst 标志传递给 combine.

如果您将 today 传递给此查询,您还必须考虑如何为 today 生成日期值。调用 datetime.date.today() 将始终为您提供服务器操作系统本地时区中的今天日期。这可能与您的 Django 设置时区或当前激活的 Django 时区不一致,这将导致查询无法给出正确的结果。为了正确处理时区,您应该使用这样的 today 函数:

from django.utils import timezone

def today():
    return timezone.localtime(timezone.now()).date()

TL;DR:正确处理日期和时间很难。希望这可以帮助;祝你好运!

这就是我最终所做的。我不想处理时区或其他任何事情,所以这很好用。

today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)

todays_pages = Page.objects.filter(date_created__gt = today)[:25]
yesterdays_pages = Page.objects.filter(date_created__gt = yesterday, date_created__lt = today)[:25]
from datetime import datetime

today = datetime.now()
current_day = Page.objects.filter(date_created__date=datetime.date(today))\
    .values('category','name')

这对我有用

灵感来自 https://docs.djangoproject.com/en/1.11/ref/models/querysets/#week