【问题标题】:Django filter on date contained by any date rangeDjango过滤任何日期范围包含的日期
【发布时间】:2019-03-05 08:17:41
【问题描述】:

我正在尝试过滤具有DateField(日期)的模型以检索日期在DateRanges 列表中的任何一个实例中的queryset,但我正在努力找出我需要的确切逻辑。

例如,如果我有以下模型:

class Period(models.Model):
    user = models.ForeignKey(User)
    range = DateRangeField()

class Game(models.Model):
    date = models.DateField()

我已经创建了 3 个不同的日期范围,如何获取日期在这 3 个日期范围之一的所有游戏的列表?

我知道我可以遍历范围并为此使用链式 Q() 过滤器,但我需要将这一切都放入一个大的 queryset 上的注释中,这将不得不使用子查询,这样就不会了没用。

我目前的努力是这样的:-

periods = Period.objects.filter(user__id=OuterRef('id')).values_list('range', flat=True)
games_in_periods = Game.objects.filter(date__contained_by=Subquery(periods))

但这不起作用,因为 contained_by 正在与日期范围进行比较,而是与日期范围的 queryset 进行比较。

感觉就像我很接近,但我一定错过了一些愚蠢的事情。

有什么想法吗?

【问题讨论】:

    标签: python django django-annotate django-subquery


    【解决方案1】:

    对于不使用 PostgreSQL 函数的人来说,有一种更通用的方法。

    class Period(models.Model):
        start = models.DateField()
        end = models.DateField()
    
    class Game(models.Model):
        date = models.DateField()
    

    然后在与Exists 配对的子查询中使用OuterRefs 来匹配介于句点之间的游戏。

    from django.db.models import OuterRef, Exists
    
    periods = Period.objects.filter(
        start__lte=OuterRef('date'), end__gte=OuterRef('date'))
    
    Game.objects
        .annotate(in_period=Exists(periods))
        .filter(in_period=True)
    

    【讨论】:

      【解决方案2】:

      我了解您的问题,关于子查询的文档不够清楚。

      你试过这种方式吗?

      periods = Period.objects.filter(user__id=OuterRef('id')).values('range')
      games_in_periods = Game.objects.filter(date__range=[Subquery(periods)])
      

      【讨论】:

        猜你喜欢
        • 2015-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-09
        • 2014-09-04
        • 2019-07-05
        • 1970-01-01
        相关资源
        最近更新 更多