У меня есть модель «Питание» с иностранным ключом «Еда». У каждого блюда есть рейтинг: хороший, плохой или равнодушный. Я хочу запросить список всех продуктов и аннотировать количество каждого типа оценки питания, но некоторые продукты еще не имеют еды, поэтому я хочу, чтобы запрос использовал LEFT OUTER JOIN, и в этом случае счетчики должны быть равны нулю.В запросе Django с условным условным выражением используется INNER JOIN. Как я могу использовать OUTER JOIN?
Я использую условные выражения в Django 1.8, и он всегда переключает связь с INNER JOIN между «Food» и «Meal». Например:
модель Питание:
class Meal(models.Model):
GOOD = 1
BAD = 2
INDIFFERENT = 3
RATING_CHOICES = (
(GOOD, 'Good'),
(BAD, 'Bad'),
(INDIFFERENT, 'Indifferent')
)
meal_time = models.DateTimeField()
food = models.ForeignKey("Food")
rating = models.IntegerField(blank=True, null=True, choices=RATING_CHOICES)
Когда я запрос Food.objects.annotate(total_meals=Count('meal'))
, Джанго генерирует запрос типа
SELECT ... FROM "Food"
LEFT OUTER JOIN "Meal" ON ...
GROUP BY "Food"
Однако, когда я добавить эти условные аннотации:
class FoodQuerySet(models.QuerySet):
def with_meal_rating_frequency(self):
return self.annotate(
total_meals=Count('meal'),
good_meals=Sum(
Case(When(meal__rating=Meal.GOOD, then=1),
output_field=models.IntegerField(), default=0)
),
bad_meals=Sum(
Case(When(meal__rating=Meal.BAD, then=1),
output_field=models.IntegerField(), default=0)
),
indifferent_meals=Sum(
Case(When(meal__rating=Meal.INDIFFERENT, then=1),
output_field=models.IntegerField(), default=0)
)
)
Вместо этого Django использует и INNER JOIN
.
SELECT ... FROM "Food"
INNER JOIN "Meal" ON ...
GROUP BY "Food"
Я знаю, что этот вопрос очень похож на this one, но его мне не ясно, как применить принятое решение моего дела. Как я могу заставить Django использовать LEFT OUTER JOIN? Ваша помощь приветствуется, спасибо!