Фильтр 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)
Другие вопросы по тегам