簡體   English   中英

Django - 如何使用 get_queryset() 返回多個查詢集 - ListView

[英]Django - How to return multiple querysets with get_queryset() - ListView

我有一個博客,其中包含查看特定用戶個人資料的選項,其中顯示了該用戶發布的帖子列表。 這些帖子在 ListView 中返回。 每個帖子還帶有評論。 因此,目前,我的get_queryset()方法返回按最高點贊總數排序的帖子評論的查詢集。

網址.py

urlpatterns = [
path('', PostListView.as_view(), name='blog-home'),
path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
]

僅顯示用戶帖子的模板。

{% for post in posts %}
<h1>{{ post.title }}</h1>
<a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>
<h3>{{ post.content }}</h3> 
{% for comment in post.comment_list %}
<h4>{{ comment }}</h4>
{% endfor %}
{% endfor %}

模型.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')

視圖.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(),但它對我不起作用。 如何返回多個查詢集 object 或從 Django 中的 get_queryset 方法添加查詢集結果

現在,這返回 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_profile'] = User.objects.filter(username=user).first()
    context['posts'] = Post.objects.filter(author=user).order_by('-date_posted')
    return context

所以我的問題是:

  • 我如何將第二個查詢集添加到get_queryset()以便我可以通過分頁從 Post model 返回兩個查詢集(僅按特定用戶過濾帖子)並顯示有序的評論 model(帖子的評論,按最高點贊在上)

  • 或者我將如何分頁

    context['posts'] = Post.objects.filter(author=user).order_by('-date_posted')

go 的正確方法是什么?

非常感激..

嘗試了兩個查詢集的 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 只能返回一個查詢集。所以我正在運行下面的代碼。

要使用默認的 ListView 實現分頁,我必須返回 model 的查詢集作為

def get_queryset(self):
    return Post.objects.filter(author=user).order_by('-date_posted')

我可以在我的模板中添加 {% for comment in post.comment_set.all %},這將顯示按評論日期排序的每個帖子的評論。

每個帖子的評論(按喜歡計數排序)必須由 get_context_data() 作為上下文返回。

但是,下面不起作用..每個帖子都有相同的評論列表..

是否有 get_context_data() 的“預取”方法? 所以我可以預取每個帖子的評論列表並按最高點排序..這是我第一個問題的延續.. Django -> ListView -> get_context_data() -> Model.objects.filter(self.object)

我確實在Django中找到了一個類似於我的問題Get related objects and how to use Prefetch with related models

class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts1.html'
context_object_name = 'posts'
paginate_by = 5

def get_queryset(self):
    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_profile'] = User.objects.filter(username=user).first()

#BELOW DOESN'T WORK. EVERY POST HAS THE SAME COMMENT LIST AS THE LATEST POST.. SEE BELOW IMAGE
    posts = Post.objects.filter(author=user).order_by('-date_posted').all()
    for post in posts:
        context['comment_list'] = post.comment_set.all().order_by("-liked")
       
        # Or Something like this???....
        # context['comment_list'] = Post.prefetch_related(
        #       Prefetch(
        #           "comment_set",
        #           # Specify the queryset to annotate and order by Count("liked")
        #           #queryset = Post.objects.annotate(like_count=Count('liked')).order_by('-like_count')
        #           queryset=Comment.objects.annotate(
        #               like_count=Count("liked")
        #           ).order_by("-like_count"),
        #           # Prefetch into post.comment_list
        #           to_attr="comment_list",
        #       )
        #   )
        return context

主頁的圖像鏈接顯示 Post.objects.all() 以及按最高點贊排序的評論

僅顯示用戶帖子的用戶個人資料圖片。 但是每個帖子都有相同的評論列表僅顯示用戶帖子的用戶個人資料圖片。但是每個帖子都有相同的評論列表pt2 僅顯示用戶帖子的用戶個人資料圖片。但是每個帖子都有相同的評論列表pt2

我認為最簡單的方法是在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",
                )
            )
        )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM