Фильтр Django по дате, содержащейся в любом диапазоне дат
Я пытаюсь отфильтровать модель, которая имеет DateField
(дата), чтобы получить queryset
случаев, чья дата есть в любом из списка DateRanges
но я изо всех сил пытаюсь понять точную логику, в которой я нуждаюсь.
Так, например, если у меня есть следующие модели:
class Period(models.Model):
user = models.ForeignKey(User)
range = DateRangeField()
class Game(models.Model):
date = models.DateField()
и я создал 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
даты
Такое ощущение, что я близко, но я, должно быть, пропустил что-то глупое.
Есть идеи?
0 ответов
Я понимаю вашу проблему, документация о 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()
Затем используйте OuterRefs
в подзапросе в паре с Exists
чтобы сопоставить игры, которые выпадают между точками.
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)