Как вызвать двойное вложенное обратное отношение внешнего ключа в django?

Я работаю над проектом форума. Сейчас мне нужно каким-то образом получить последние сообщения для каждой категории.

Структура моих моделей следующая (псевдокод):

class Category(models.Model):
   ...

class Topic(models.Model):
   category = models.ForeignKey(Category, on_delete=models.CASCADE)
   ...

class Post(models.Model):
   topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
   ...

Мне нужно получить последние Post объекты внутри Category функций модели, чтобы я мог вызвать их позже в моем шаблоне.

При одиночном обратном вызове внешнего ключа я бы сделал что-то вроде: category: Category = self.topic_set.all() но мне нужно углубиться на один уровень для Post.

Есть ли более разумный способ сделать это вместо понимания списка как [topic.post_set.first() for topic in self.topic_set.all()] ??

Вы можете сделать это двумя запросами с Subquery выражением [Django-doc], которое будет получать последние Post за Topic:

from django.db.models import OuterRef, Subquery

post_ids = Topic.objects.filter(
    category=my_category
).values_list(
    Subquery(
        Post.objects.filter(
            topic_id=OuterRef('pk')
        ).order_by('-created').values('pk')[:1]
    ),
    flat=True
)

posts = Post.objects.filter(pk__in=post_ids)
Вернуться на верх