Django - Как вернуть несколько наборов запросов с помощью get_queryset() - ListView
У меня есть блог с возможностью просмотра профиля конкретного пользователя, в котором отображается список постов, опубликованных пользователем. Посты возвращаются в ListView. Каждый пост также сопровождается комментариями. В настоящее время мой метод get_queryset() возвращает набор комментариев к посту, упорядоченный по общему количеству наибольших лайков
models.py
class Post(models.Model):
title = models.CharField(max_length=100, help_text="100 characters or less")
content = models.TextField()
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
liked = models.ManyToManyField(Profile, blank=True, related_name='likes')
class Comment(models.Model):
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
body = models.TextField(max_length=300)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
liked = models.ManyToManyField(Profile, blank=True, related_name='com_likes')
views.py
class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 5
def get_queryset(self):
return (
super()
.get_queryset()
# Prefetch comment using a Prefetch object
.prefetch_related(
Prefetch(
"comment_set",
# Specify the queryset to annotate and order by Count("liked")
queryset=Comment.objects.annotate(
like_count=Count("liked")
).order_by("-like_count"),
# Prefetch into post.comment_list
to_attr="comment_list",
)
)
)
Как вернуть другой кверисет? Я прочитал в другом обсуждении, что нужно использовать chain(), но у меня это не сработало. Как вернуть несколько объектов queryset или добавить результат queryset из метода get_queryset в Django
Сейчас это возвращает Post.objects.all(). Но я хочу вернуть
#второй кверисет
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-date_posted')
Я мог бы добавить это в контекст, как показано ниже, но пагинатор не работает, и я не уверен, что это правильный способ обработки.
def get_context_data(self, *args, **kwargs):
# context = super(UserPostListView, self).get_context_data(*args, **kwargs)
context = super().get_context_data(*args, **kwargs)
user = get_object_or_404(User, username=self.kwargs.get('username'))
context['user_pro'] = User.objects.filter(username=user).first()
context['posts'] = Post.objects.filter(author=user).order_by('-date_posted')
return context
Итак, мои вопросы следующие:
Как мне добавить второй кверисет в get_queryset() чтобы я мог возвращать оба набора запросов из модели Post и модели Comment с пагинацией
Или как бы я сделал пагинацию context['posts'] = Post.objects.filter(author=user).order_by('-date_posted')
и какой правильный путь для этого выбрать?
Очень признателен...
попытался выполнить chain() двух наборов запросов, но получил ошибку unhashable type: 'slice'
также попробовал ниже, но та же ошибка:
# def get_queryset(self):
# user = get_object_or_404(User, username=self.kwargs.get('username'))
# posts = Post.objects.filter(author=user).order_by('-date_posted')
# queryset = {
# "users_posts": posts,
# "comment_list":
# super().get_queryset()
# # Prefetch comment using a Prefetch object gives you more control
# .prefetch_related(
# Prefetch(
# "comment_set",
# # Specify the queryset to annotate and order by Count("liked")
# queryset=Comment.objects.annotate(
# like_count=Count("liked")
# ).order_by("-like_count"),
# # Prefetch into post.comment_list
# to_attr="comment_list",
# )
# )
# }
# return queryset
изображение домашней страницы, например
Я думаю, что самый простой способ сделать это - фильтровать по автору/пользователю в get_queryset.
class UserPostListView(ListView):
model = Post
template_name = "blog/user_posts.html"
context_object_name = "posts"
ordering = ["-date_posted"]
paginate_by = 5
def get_queryset(self):
return (
super()
.get_queryset()
# Filter by author/user
.filter(author__username=self.kwargs.get('username'))
# Prefetch comment using a Prefetch object gives you more control
.prefetch_related(
Prefetch(
"comment",
# Specify the queryset to annotate and order by Count("liked")
queryset=Comment.objects.annotate(
like_count=Count("liked")
).order_by("-like_count"),
# Prefetch into post.comment_list
to_attr="comment_list",
)
)
)