【问题标题】:Django filter when current time falls between two TimeField values当前时间介于两个 TimeField 值之间时的 Django 过滤器
【发布时间】:2017-02-10 23:06:06
【问题描述】:

我将一个对象存储在我的数据库中,其时间字段如下:

class MyClass(models.Model):

    start_time = models.TimeField(null=True, blank=True)
    stop_time = models.TimeField(null=True, blank=True)

这里的想法是,当查询端点时,服务器将只返回当前时间在 start_time 和 stop_time 之间的对象。

注意:start_time 和 stop_time 是一天中的任意时间,可以跨越午夜,但永远不会超过 24 小时。

我试过了

currentTime = datetime.now().time()
MyClass.objects.filter(stop_time__gte=currentTime, start_time__lte=currentTime)

但这不考虑时间跨度的时间。

我确信必须有一个简单的解决方案,但网络搜索让我一无所获。有谁知道这样做的好方法吗?

【问题讨论】:

    标签: django time django-models django-views


    【解决方案1】:

    仅供参考,我也在这里发布(我之前也在另一个链接问题中回答了这个问题)。您需要在您的 filter() 子句中使用类似的东西来处理午夜穿越和非午夜穿越情况所需的不同比较。将 daily_starts/ends_at 替换为您的开始/停止时间,将 now_time 替换为您的 currentTime。

    (Q(daily_starts_at__lte=F('daily_ends_at')) &
     Q(daily_starts_at__lte=now_time, daily_ends_at__gte=now_time)) |   
    (Q(daily_starts_at__gt=F('daily_ends_at')) &
     (Q(daily_starts_at__lte=now_time) | Q(daily_ends_at__gte=now_time))
    

    如果需要,您还需要使用包含其他过滤器参数的 Q() 子句进行 &。

    【讨论】:

      【解决方案2】:

      经过一番挖掘,我发现这需要两个查询:一个是当开始时间小于停止时间时(常见情况),一个是当它大于停止时间时(不常见,后- 午夜案件)。

      代码如下:

      currentTime = datetime.now().time()
      
      #Returns a list of menus that have start times less than their stop times
      list_1 = MyClass.objects.filter(Q(start_time__lte=F('stop_time')), Q(start_time__lte=currentTime), stop_time__gte=currentTime)
      
      #Returns the menus that have start times greater than their stop times (span midnight)
      list_2 = MyClass.objects.filter(Q(start_time__gt=F('stop_time')), Q(start_time__lte=currentTime) | Q(stop_time__gte=currentTime))
      
      concat_list = list_1 | list_2
      concat_list = concat_list.order_by('-priority')
      

      因为我们使用“|”要连接列表,我们可以保留与原始列表相同的特征,例如“order_by()”。仅当连接的数据来自同一模型集时才会出现这种情况。

      参考资料:

      Django After Midnight Business Hours TimeField Comparison Error

      How to combine 2 or more querysets in a Django view?

      【讨论】:

      • 只是澄清MyClass.objects.filter(...) 不返回列表,它返回一个查询集,并且您正在对这些查询集执行 OR 操作,这将返回一个新的查询集。 order_by() 是 Querysets 的一种方法。
      • 这确实是两个非常难的查询。如果你看一下,你有多个 OR 条件和联合,所有这些都很难在 Mysql 或 sqlite 等低端数据库上优化。但是在不知道为什么你不能为这些值设置日期的情况下,我也不能改变我的答案
      • @e4c5 - 我可能理解错了,但我的理解是,通过使用特定的日期值,我将自己限制在与这些时间相关的日期,对吗?我单独使用时间值的原因是它们日复一日地持续存在,我不想为了保持系统正常运行而更新日期值。是不是更清楚了?
      • 不是真的,但既然你坚持了一些似乎对你有用的东西,我认为你可以这样做:-)
      猜你喜欢
      • 2021-06-29
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多