Ваша помощь будет оценена по достоинству! Спасибо.
Я создаю сайт, который отображает фотоальбомы. Для этого у меня есть следующие модели.
class Medium(models.Model):
pass
class MediaSet(models.Model):
media = models.ManyToManyField("Medium", related_name="sets", through="SetContent", through_fields=('set', 'medium'),)
class SetContent(models.Model):
is_cover = models.BooleanField(default=None, null=True)
set = models.ForeignKey("MediaSet", on_delete=models.CASCADE, related_name="set_content")
medium = models.ForeignKey("Medium", on_delete=models.CASCADE, related_name="set_contents")
У каждого медиасета (=альбома) может быть обложка. Если нет, то я просто использую первое попавшееся изображение.
Теперь я пытаюсь оптимизировать БД путем сокращения запросов. Я работаю над MediaSetListView, который перечисляет медиа-наборы. Возможно ли на уровне запроса аннотировать или Prefetch() обложку (один Medium) в зависимости от того, существует ли is_cover или нет?
Другими словами: Получить список всех медиасетов и добиться, чтобы каждый медиасет имел обложку, которая является либо носителем, отмеченным как "is_cover" в SetContent, либо первым носителем в SetContent.
В настоящее время у меня есть эта логика в модели, но это приводит к тоннам запросов, которые мне не нужны.
Спасибо за помощь.
Как насчет добавления ссылки на обложку в класс MediaSet и использования декоратора свойств? Это избавит вас от лишней колонки в таблице manytomany, и я предполагаю, что у вас никогда не будет больше одной обложки на альбом, верно? Тогда это отношение должно быть отражено в классе MediaSet, на мой взгляд. Тогда, кстати, вы могли бы избавиться и от класса SetContent
class MediaSet(models.Model):
_cover = models.ForeignKey("Medium", blank=true, null=true, on_delete=models.SET_NULL)
media = models.ManyToManyField("Medium", related_name="albums")
@property
def cover(self):
if self._cover:
return self._cover
else:
return self.media.first()
@cover.setter
def cover(self, value):
self._cover = value