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



我正在尝试过滤一个具有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

感觉我很接近,但我一定错过了一些愚蠢的东西。

有什么想法吗?

我理解你的问题,关于Subquery的文档不够清楚。

你试过这种方式吗?

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

对于不使用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)

最新更新