Django数据库查询:如何按日期范围过滤对象?

时间:2022-08-25 10:26:59

I've got a field in one model like

我在一个模型中有一个字段。

class Sample(models.Model):
    date = fields.DateField(auto_now=False)

Now, I need to filter the objects by a data range, for example, all the objects that has date between 1 Jan 2011 to 31 Jan 2011?

现在,我需要通过一个数据范围来过滤对象,例如,2011年1月1日到2011年1月31日之间的所有对象?

Thanks for your help!

谢谢你的帮助!

5 个解决方案

#1


287  

Use

使用

Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])

Or if you are just trying to filter month wise:

或者如果你只是试着去筛选一个月的智慧:

Sample.objects.filter(date__year='2011', 
                      date__month='01')

Edit

As Bernhard Vallant said, if you want a queryset which excludes the specified range ends you should consider his solution, which utilizes gt/lt (greater-than/less-than).

正如Bernhard Vallant所说,如果您想要一个不包含指定范围的queryset,您应该考虑他的解决方案,它使用gt/lt(大于/小于)。

#2


126  

You can use django's filter with datetime.date objects:

您可以使用django的过滤器与datetime。日期对象:

import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
                                sampledate__lte=datetime.date(2011, 1, 31))

#3


60  

When doing django ranges with a filter make sure you know the difference between using a date object vs a datetime object. __range is inclusive on dates but if you use a datetime object for the end date it will not include the entries for that day if the time is not set.

当使用一个过滤器进行django范围时,请确保您知道使用date对象与datetime对象之间的区别。__range是包含在日期上的,但是如果您使用datetime对象作为结束日期,如果时间没有设置,它将不包括当天的条目。

    startdate = date.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

returns all entries from startdate to enddate including entries on those dates. Bad example since this is returning entries a week into the future, but you get the drift.

从startdate返回所有条目,包括这些日期的条目。这是一个糟糕的例子,因为这是一个星期返回到未来的条目,但是你得到了漂移。

    startdate = datetime.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

will be missing 24 hours worth of entries depending on what the time for the date fields is set to.

将会丢失24小时的条目,这取决于日期字段设置的时间。

#4


15  

You can get around the "impedance mismatch" caused by the lack of precision in the DateTimeField/date object comparison -- that can occur if using range -- by using a datetime.timedelta to add a day to last date in the range. This works like:

通过使用datetime,您可以绕过DateTimeField/date对象比较中缺乏精确的“阻抗失配”。timedelta在该范围内添加一天到最后一天。这就像:

start = date(2012, 12, 11)
end = date(2012, 12, 18)
new_end = end + datetime.timedelta(days=1)

ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])

As discussed previously, without doing something like this, records are ignored on the last day.

如前所述,在不做类似的事情的情况下,记录在最后一天被忽略。

Edited to avoid the use of datetime.combine -- seems more logical to stick with date instances when comparing against a DateTimeField, instead of messing about with throwaway (and confusing) datetime objects. See further explanation in comments below.

与DateTimeField进行比较时,更符合逻辑地使用日期实例,而不是使用一次性(和混乱的)datetime对象。请在下面的评论中看到进一步的解释。

#5


1  

Works for me

适合我

YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())

#1


287  

Use

使用

Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])

Or if you are just trying to filter month wise:

或者如果你只是试着去筛选一个月的智慧:

Sample.objects.filter(date__year='2011', 
                      date__month='01')

Edit

As Bernhard Vallant said, if you want a queryset which excludes the specified range ends you should consider his solution, which utilizes gt/lt (greater-than/less-than).

正如Bernhard Vallant所说,如果您想要一个不包含指定范围的queryset,您应该考虑他的解决方案,它使用gt/lt(大于/小于)。

#2


126  

You can use django's filter with datetime.date objects:

您可以使用django的过滤器与datetime。日期对象:

import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
                                sampledate__lte=datetime.date(2011, 1, 31))

#3


60  

When doing django ranges with a filter make sure you know the difference between using a date object vs a datetime object. __range is inclusive on dates but if you use a datetime object for the end date it will not include the entries for that day if the time is not set.

当使用一个过滤器进行django范围时,请确保您知道使用date对象与datetime对象之间的区别。__range是包含在日期上的,但是如果您使用datetime对象作为结束日期,如果时间没有设置,它将不包括当天的条目。

    startdate = date.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

returns all entries from startdate to enddate including entries on those dates. Bad example since this is returning entries a week into the future, but you get the drift.

从startdate返回所有条目,包括这些日期的条目。这是一个糟糕的例子,因为这是一个星期返回到未来的条目,但是你得到了漂移。

    startdate = datetime.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

will be missing 24 hours worth of entries depending on what the time for the date fields is set to.

将会丢失24小时的条目,这取决于日期字段设置的时间。

#4


15  

You can get around the "impedance mismatch" caused by the lack of precision in the DateTimeField/date object comparison -- that can occur if using range -- by using a datetime.timedelta to add a day to last date in the range. This works like:

通过使用datetime,您可以绕过DateTimeField/date对象比较中缺乏精确的“阻抗失配”。timedelta在该范围内添加一天到最后一天。这就像:

start = date(2012, 12, 11)
end = date(2012, 12, 18)
new_end = end + datetime.timedelta(days=1)

ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])

As discussed previously, without doing something like this, records are ignored on the last day.

如前所述,在不做类似的事情的情况下,记录在最后一天被忽略。

Edited to avoid the use of datetime.combine -- seems more logical to stick with date instances when comparing against a DateTimeField, instead of messing about with throwaway (and confusing) datetime objects. See further explanation in comments below.

与DateTimeField进行比较时,更符合逻辑地使用日期实例,而不是使用一次性(和混乱的)datetime对象。请在下面的评论中看到进一步的解释。

#5


1  

Works for me

适合我

YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())