简体   繁体   English

Django过滤任何日期范围包含的日期

[英]Django filter on date contained by any date range

I'm trying to filter a model which has a DateField (date) to retrieve a queryset of instances whose date is in any one of a list of DateRanges but I'm struggling to figure out the exact logic I need.我试图筛选具有一个模型DateField (日期)来检索queryset情况下,其日期是在列表中的任何一个的DateRanges但我在努力找出确切的逻辑,我需要。

So for example, if I have the following models:例如,如果我有以下模型:

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

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

and I've created 3 different date ranges, how do I get a list of all the Games whose date is in one of those 3 date ranges?并且我创建了 3 个不同的日期范围,如何获取日期在这 3 个日期范围之一内的所有游戏的列表?

I know I can iterate through the ranges and use a chained Q() filter for this but I need to put this all into an annotation on a large queryset which is going to have to use a Subquery so that won't work.我知道我可以通过迭代的范围,并使用链Q()此过滤器,但我需要把所有这一切到注释上的大型queryset其将不得不使用子查询,这样就不会工作。

My current effort looks like this:-我目前的努力看起来像这样:-

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

but that doesn't work because the contained_by is being compared to a daterange but a queryset of dateranges.但由于不工作contained_by被比作日期范围但queryset dateranges的。

It feels like I'm close but I must have missed something silly.感觉就像我很接近,但我一定错过了一些愚蠢的事情。

Any ideas?有任何想法吗?

I understand your problem, documentation about Subquery is not enough clear.我理解你的问题,关于子查询的文档不够清楚。

Have you tried in this way?你试过这种方法吗?

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

There is a more generic way to do this for people not using PostgreSQL functions.对于不使用 PostgreSQL 函数的人,有一种更通用的方法可以做到这一点。

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

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

Then use OuterRefs in a subquery paired with an Exists to match up games that fall between a period.然后在与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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM