【问题标题】:Django After Midnight Business Hours TimeField Comparison Error午夜营业时间后的 Django 时间字段比较错误
【发布时间】:2015-06-05 22:25:00
【问题描述】:

我有一个需要比较的营业时间,如果营业时间超过午夜,我会得到不完整的结果

我的模特

class Hours(models.Model):
  dayofweek = models.ForeignKey('Dayofweek')
  opentime = models.TimeField(blank=True, null=True)
  closetime = models.TimeField(blank=True, null=True)
  ...

如果我只需要显示小时数,一切正常,例如: 周六下午 5 点至凌晨 2 点

现在,当我尝试查询营业时间以检查商家是否营业时,那些过去午夜营业时间的人将返回 Falseexists()

我的查询

if Hours.objects.filter(
            business__id=id,
            dayofweek__pyday=dt, 
            opentime__lte=mytime, 
            closetime__gte=mytime).exists():
    #do something

有什么建议可以告诉 Django 凌晨 2 点是下午 5 点之后吗?

【问题讨论】:

  • 为什么不做 2 次查询... (5pm -11:59 pm) || (上午 12 点 - 凌晨 2 点)?听起来 api 没有设置为你想要的?我的猜测是你可以菊花链 2 个过滤器... Hours.objects.filter().filter().exists()
  • 好吧,如果营业时间只是下午 5 点到 10 点,那该怎么办?例如,该应用正在检查下午 5 点到 10 点的商家是否在晚上 9 点营业?
  • 请注意:如果当前时间是凌晨 2 点,您也会遇到同样的问题:关闭时间会匹配,而不是开放时间。
  • 有点跑题了,你为什么决定将 dayofweek 设置为 ForeignKey。而不是例如IntegerField with options = ((1, 'Monday'), (2, 'Tuesday'),..
  • Maxim,主要原因是当我在数据库中拥有它时,我可以每天都有额外的字段。例如,除了常规名称Monday,我还有Mon 的缩写版本,并且我还存储Python 日期,其中Sunday 是0,因此我不必运行任何转换。

标签: python django


【解决方案1】:

一天可以有多个时段,但无论如何,一天都会在晚上 11:59 结束。如果这延续到第二天,你必须打破你的时间间隔。所以你的过滤器的逻辑将是这样的......

# Spans over 2 days
if opentime > closetime:
  Hours.objects.filter(
    business_id=id,
    dayofweek_pyday=dt,
    opentime_tye=myOpenTime,
    closetime_gte=11:59:99
  ).exists() ||
  Hours.objects.filter(
    business_id=id,
    # Next date
    dayofweek_pyday=dt + 1,
    opentime_tye=00:00:00,
    closetime_gte=myCloseTime
  ).exists()
# Spans over 1 day
else:
   Hours.objects.filter(
   business__id=id,
   dayofweek__pyday=dt, 
   opentime__lte=myOpentime, 
   closetime__gte=myClosetime).exists()

我不了解 django,所以这只是一些伪代码和我将使用的替代方法。

【讨论】:

  • 感谢您的反馈。这种方法肯定会奏效。我想唯一的缺点是我必须先运行另一个查询才能获得开放时间和关闭时间,以便我可以比较它们。
  • 您只需查看 api 文档,看看它是否符合您的要求,但这是我解决该问题的技巧。如果有什么不使用 Hours.objects ...如果你可以做绝对 UTC 时间,那会更有意义,你可以查询你想要的方式。查看 api 文档。我认为您实际上使用了错误的查询服务。
【解决方案2】:

通过两个查询使用F and Q expressions怎么样:

一个简单的案例(开放时间

Hours.objects.filter(
         opentime__lte=F('closetime'),
         business__id=id,
         dayofweek__pyday=dt, 
         opentime__lte=mytime, 
         closetime__gte=mytime).exists():

一个用于奇数情况(关闭时间

Hours.objects.filter(
         opentime__gt=F('closetime'),
         business__id=id,
         dayofweek__pyday=dt, 
         Q(opentime__lte=mytime) | Q(closetime__gte=mytime)).exists():

【讨论】:

  • 感谢您的替代方案,我也一定会尝试此解决方案!感谢您的帮助!
  • 我遇到了类似的问题,这正是我想要解决的问题。
  • 此代码不起作用,因为关键字 opentime__lte 在 filter 子句中重复了两次。
【解决方案3】:
(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))

这就是我解决相同情况的方法,在您的 filter() 子句中使用它(并将我的 daily_starts/ends_at 替换为您的姓名,将 now_time 替换为 now().time() 或其他内容)。逻辑与此处的其他答案一样,比较必须根据范围是否超过午夜而有所不同。

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

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 2015-04-11
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多