Получение набора запросов django из обратной связи по внешнему ключу с одним отдельным полем - PullRequest
0 голосов
/ 09 мая 2019

Использование Django 1.8

Я пытаюсь получить набор запросов с помощью обратной связи по внешнему ключу, когда в исходных моделях есть только одно отдельное значение из одного поля.

class Franchise(models.Model):
    ...

class Title(models.Model):
    franchise = models.ForeignKey(Franchise, related_name='titles')
    genre = models.CharField(max_length=20)
    ...

Итак, в этом примере я хотел бы получить набор запросов объектов франшизы, у которых все названия имеют одинаковый жанр. Я могу добавить методы в модель франшизы и сгенерировать список идентификаторов франшизы, чтобы получить набор запросов, но это очень медленно.

class Franchise(models.Model):
    ...

    def get_title_genres(self):
        self.titles.values_list('genre', flat=True).distinct()

    def is_single_genre(self):
        return len(self.get_title_genres()) == 1


franchise_ids = [
   franchise.id
   for franchise in Franchise.objects.all()
   if franchise.is_single_genre()
]

queryset = Franchise.objects.filter(id__in=franchise_ids)

Есть ли более эффективный способ сделать это?

1 Ответ

1 голос
/ 09 мая 2019

Если вам не нужен набор запросов, вам не нужен второй набор запросов с id__in=franchise_ids.

franchises = [
    franchise for franchise in Franchise.objects.all()
    if franchise.is_single_genre()
]

Вы можете использовать prefetch_related для извлечения всех связанных заголовков с набором запросов, однако вы не сможете повторно использовать метод get_title_genres, потому что values_list(...).distinct() вызовет новый запрос SQL.

franchises = [
    franchise for franchise in Franchise.objects.prefetch_related('titles')
    if len(set(t.genre for t in franchise.titles)) == 1
]
...