我在一个模型中有一个字段,例如:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
现在,我需要按日期范围过滤对象。
如何过滤日期在 1-Jan-2011
和 31-Jan-2011
之间的所有对象?
利用
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
或者,如果您只是想按月过滤:
Sample.objects.filter(date__year='2011',
date__month='01')
编辑
正如 Bernhard Vallant 所说,如果您想要一个不包括 specified range ends
的查询集,您应该考虑使用 gt/lt(大于/小于)的 his solution。
您可以将 django's filter
与 datetime.date
objects 一起使用:
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
在使用过滤器执行 django 范围时,请确保您知道使用日期对象与日期时间对象之间的区别。 __range 包含日期,但如果您使用 datetime 对象作为结束日期,如果未设置时间,它将不包括当天的条目。
from datetime import date, timedelta
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
返回从 startdate 到 enddate 的所有条目,包括这些日期的条目。不好的例子,因为这是在未来一周返回条目,但你得到了漂移。
from datetime import datetime, timedelta
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
将丢失 24 小时的条目,具体取决于日期字段设置的时间。
date
对象:>>> from datetime import date
>>> startdate = date.today()
您可以通过使用 datetime.timedelta strong> 将日期添加到范围内的最后一个日期。这就像:
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])
如前所述,如果不执行此类操作,最后一天的记录将被忽略。
编辑以避免使用 datetime.combine
- 在与 DateTimeField
比较时坚持使用日期实例似乎更合乎逻辑,而不是搞乱一次性(和令人困惑的)datetime
对象。请参阅下面的评论中的进一步解释。
Example.objects.filter(created__range=[date(2014, 1, 1), date(2014, 2, 1)])
不会包括在 date(2014, 2, 1)
上创建的对象,正如@cademan 所解释的那样。但是,如果您通过添加一天来增加结束日期,您将获得一个查询集,涵盖那些丢失的对象(并且由于相同的怪癖而方便地省略在 date(2014, 2, 2)
上创建的对象)。这里令人讨厌的是用 created__gte ... created__lte=date(2014, 2, 1)
指定的“手动”范围也不起作用,这绝对是违反直觉的恕我直言。
例如,您可以使用“__range”:
from datetime import datetime
start_date=datetime(2009, 12, 30)
end_date=datetime(2020,12,30)
Sample.objects.filter(date__range=[start_date,end_date])
为了使其更灵活,您可以设计一个 FilterBackend 如下:
class AnalyticsFilterBackend(generic_filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
predicate = request.query_params # or request.data for POST
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is not None:
queryset = queryset.filter(your_date__range=(predicate['from_date'], predicate['to_date']))
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is None:
queryset = queryset.filter(your_date__gte=predicate['from_date'])
if predicate.get('to_date', None) is not None and predicate.get('from_date', None) is None:
queryset = queryset.filter(your_date__lte=predicate['to_date'])
return queryset
很简单,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
为我工作
模型
date = models.DateField()
看法
def get_queryset(self):
fromDate = self.request.query_params.get('fromDate',None)
toDate = self.request.query_params.get('toDate',None)
response = yourModel.objects.filter(date__gte=fromDate,date__lte=toDate)
return response
__range
包括边框(如 sql 的BETWEEN
),如果您不希望包含边框,则必须使用我的 gt/lt 解决方案...order_by
而不是上述filter
生成的QuerySet
。我已经好几年没用过 Django 了。