Джанго быстро становится последним в отношениях один ко многим

У меня есть модель в Джанго, как это

class Artist(models.model):
    pass

class Track(models.model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)

У меня есть только пара сотен Artists, которые я хочу показать на странице рядом с их последними Track, Я могу получить все Artistбыстро, но выбирая их последние Track, когда есть тысячи треков, оказывается дорого.

latest_track = artist.track_set.latest('when') # really expensive

То, как я добавляю треки к исполнителю, позволяет мне легко устанавливать последний трек исполнителя (т.е. мне не нужно беспокоиться о нескольких потоках). Это заставило меня думать, что я должен просто хранить поле Artist#latest_track, но я не знаю, как смоделировать это, потому что это не совсем OneToOneFieldи это самое близкое, что я мог найти.

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

Что мне здесь делать?

1 ответ

Решение

Бьюсь об заклад, вам просто нужно prefetch_related по художникам:

for artist in Artist.objects.all().prefetch_related('track_set'):
    latest_track = artist.track_set.latest('when') #should be no db hit

Если он все еще медленный, вам нужно проверить сгенерированный sql (панель инструментов отладки django, журналы БД) и посмотреть, что происходит, часто медлительность происходит не там, где вы ожидаете.

Другие вопросы по тегам