【问题标题】:Django ORM: filter by hour rangeDjango ORM:按小时范围过滤
【发布时间】:2013-11-26 07:50:02
【问题描述】:

我正在尝试实现一个小时范围的过滤器,它应该返回日期在 hourA 和 hourB 之间的记录(即:“给我在下午 16 点到 18 点之间保存的记录”)。 我的尝试:

1) 使用新的 1.6 __hour 过滤器和 __in__range

MyModel.objects.filter(date__hour__in=(16, 17, 18))
MyModel.objects.filter(date__hour__range=(16, 18))

上面的代码产生异常

2) 使用 Q 对象:

hList = [Q(date__hour=h) for h in (16, 17, 18)]
MyModel.objects.filter(reduce(operator.or_, hList))

此版本有效,但效率非常低,因为在该范围内的每个小时,它都会重复 extract() 调用,生成类似以下内容:

   where 
   extract(hour from date) = 16 or 
   extract(hour from date) = 17 or 
   extract(hour from date) = 18

什么时候正确的原始 SQL 应该是:

where extract(hour from date) in (16, 17, 18)

...如何在不依赖原始 sql 的情况下有效地按小时范围进行过滤?

【问题讨论】:

  • __gte__lte 代替__in 怎么样?
  • 你的意思是 date__hour__gte 和 date__hour__lte 吗?如果是这样,据我所知,不可能以这种方式链接过滤器:(
  • @daveoncode 你有没有想过?我有同样的问题。
  • 不幸的是没有:( ...目前唯一的方法是使用原始 SQL(如果您关心优化)...我希望未来版本的 Django 将实现这种过滤器,或者一种扩展现有方法的简单方法:P

标签: sql django django-orm


【解决方案1】:

Django 1.9+ you can chain hour lookups 中,因此问题中的示例将起作用:

MyModel.objects.filter(date__hour__in=(16, 17, 18))
MyModel.objects.filter(date__hour__range=(16, 18))

【讨论】:

    【解决方案2】:

    我设法以这种方式解决了这个问题:

        all_points = MyModel.objects.all()
        all_points.extra(where=['extract(hour from MyDateField) in (16, 17, 18)'])
    

    【讨论】:

      猜你喜欢
      • 2019-07-05
      • 2017-08-05
      • 2022-08-14
      • 2012-12-16
      • 1970-01-01
      • 2020-03-09
      • 2014-09-04
      • 2014-07-22
      • 1970-01-01
      相关资源
      最近更新 更多