У меня есть две следующие модели:
class Tour(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=3000, blank=True
# some other fields here
и
class TourDatesInfo(models.Model):
departure_date = models.DateTimeField()
return_date = models.DateTimeField()
tour = models.ForeignKey(Tour, on_delete=models.CASCADE, related_name='dates')
Модель Tour
имеет отношение «один ко многим» с TourDatesInfo
, поэтому один тур может иметь несколько разных наборов дат отправления/возвращения.
Чего я пытаюсь добиться, так это иметь возможность фильтровать туры QuerySet
в зависимости от их набора TourDatesInfo
, а именно в зависимости от того, содержит ли каждый тур пару отправления/возврата, которая удовлетворяет определенным условиям, например, получить все туры, которые имеют хотя бы один TourDatesInfo
с departure_date
> 12.04.2022 и return_date
< 01.05.2022.
Я могу написать SQL-запрос для этого, что-то вроде SELECT * FROM tours_tour tours WHERE tours.id IN (SELECT DISTINCT tour_id FROM tours_tourdatesinfo WHERE departure_date > '2022-04-12' AND return_date < '2022-05-01');
, но как это можно сделать с помощью django ORM без необработанных запросов?
Вы можете фильтровать с помощью:
Tour.objects.filter(
dates__departure_date__gt='2022-04-12',
dates__return_date__lt='2022-05-01'
).distinct()
Это создаст JOIN
в таблице модели TourDatesInfo
и отфильтрует departure_date
и return_date
. Если есть такой TourDatesInfo
, он вернет данные Tour
. Звонок .distinct()
[Django-doc] используется для предотвращения возврата одного и того же Tour
столько раз, сколько есть совпадающих TourDatesInfo
s.