【问题标题】:Properly make a BETWEEN clause in DjangoORM在 Django ORM 中正确创建 BETWEEN 子句
【发布时间】:2017-05-01 23:50:58
【问题描述】:

我在使用 DjangoORM 在我的数据库中查询所需结果时遇到问题。

这是我的模型。

class HeatWatchList(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                   related_name='watchlist_users', on_delete=models.CASCADE)

    heat = models.OneToOneField(Heat, related_name='heat_watch_list', 
                   on_delete=models.CASCADE)

    next_date_from = models.DateTimeField()
    next_date_to = models.DateTimeField()

我想获取今天日期在 next_date_fromnext_date_to 字段之间的所有记录。

我可以在原始 sql 中轻松做到这一点:

SELECT 
    *
FROM
    farm_management_db.heat_heatwatchlist
WHERE
    DATE(now()) BETWEEN DATE(next_date_from) AND DATE(next_date_to);

这是我迄今为止尝试过的,但我没有得到任何记录:

HeatWatchList.objects.filter(
                next_date_from__date__gte=datetime.now().date(),
                next_date_to__date__lte=datetime.now().date()
            )    

【问题讨论】:

  • datetime.now() 不是 2017-01-23
  • 很抱歉是now()
  • 这个修改后的原始查询会产生任何结果吗?
  • 那么 ORM 查询会产生一个类似于您的原始查询的查询。几行样本数据可能有帮助[
  • 它不会产生任何我只是删除__date 并像next_date_from__ltenext_date_to__gte 一样修复它才能工作的东西,但它包括时间查询,我不知道如何排除时间。

标签: python mysql django django-models django-orm


【解决方案1】:

您可以在模型中添加一个函数。

def is_between_date(self): if Timezone.zone() > next_date_from and timezone.zone() < next_date_to: return True return False

【讨论】:

    【解决方案2】:

    您应该尝试以下代码(通过删除 __date):

    HeatWatchList.objects.filter(
                    next_date_from__gte=datetime.now().date(),
                    next_date_to__lte='2017-01-23'
                )   
    

    【讨论】:

    • 这部分解决了它,但我有一个模型。DateTimeField 所以当我查询时我想排除时间。
    • 应该是 next_date_from__lte 和 next_date_to__gte 才能正常工作,但查询包括时间。
    • 解决此问题的方法是使用 Dajngo DateField 而不是 DateTimeField,或者,您可以将比较值构造为具有“T00:00:00”和“23:59:59”的 DatetimeField
    • 哦,太可悲了,但我想我会坚持这一点,这是实现这种方法的最佳方式。但是你能把next_date_from__gte=datetime.now().date(), next_date_to__lte='2017-01-23'改为next_date_from__lte=datetime.now().date(), next_date_to__gte=datetime.now().date()吗?它现在工作
    • 除非将上面的代码更改为next_date_from__lte=datetime.now().date(), next_date_to__gte=datetime.now().date(),否则它可以部分工作
    【解决方案3】:

    您可以这样做(通过删除__date)并使用datetime.combine

    from datetime import  datetime, time
    
    HeatWatchList.objects.filter(
                    next_date_from__gte=datetime.combine(datetime.now().date(), time.min),
                    next_date_to__lte=datetime.combine(datetime.now().date(), time.max)
                )
    

    【讨论】:

    • 这和阴暗的答案一样
    • 取决于时间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多