使用get_queryset订购listview

时间:2017-09-26 14:05:31

标签: django django-orm

两种模式:帖子和作者
此视图显示每个作者的最后一个帖子(作者是ForeignKey)

我想按降序排列这些帖子,但它不起作用。 模板以升序方式继续显示这些内容。 我试着这个:

views.py

class LastestListView(ListView):
    context_object_name = 'posts'
    model = models.Post
    ordering = ['-date']
    paginate_by = 10

    def get_queryset(self):
        return self.model.objects.filter(pk__in=
        Post.objects.values('author__id').annotate(
            max_id=Max('id')).values('max_id'))

或:

class LastestListView(ListView):
    context_object_name = 'posts'
    model = models.Post
    paginate_by = 10

    def get_queryset(self):
        return self.model.objects.filter(pk__in=
        Post.objects.order_by('-date').values('author__id').annotate(
            max_id=Max('id')).values('max_id'))

解决方案

必须在Queryset的开头设置排序:

class LastestListView(ListView):
    context_object_name = 'posts'
    model = models.Post
    paginate_by = 10

    def get_queryset(self):
        return self.model.objects.order_by('-date').filter(pk__in=
        Post.objects.values('author__id').annotate(
            max_id=Max('id')).values('max_id'))

1 个答案:

答案 0 :(得分:0)

更确切地说,排序应该应用于主查询,而不是应用于子查询。我更喜欢过滤后的排序,这只是意见问题。

def get_queryset(self):
    qs = (
        self.model.objects
        .filter(
            pk__in=(
                Post.objects
                .values('author_id')
                .annotate(max_id=Max('id'))
                .values('max_id')
            )
        )
        .order_by('-date')
    )
    # print(str(qs.query))   # SQL check is perfect for debugging
    return qs

使用严格缩进的更稀疏样式可能有助于编写易于阅读的代码。优点是您可以通过更改行的顺序来更轻松地注释掉方法或更改方法的顺序。您还清楚地看到order_by位于主查询或子查询中。