【问题标题】:Ordering listview with get_queryset使用 get_queryset 排序列表视图
【发布时间】:2017-09-26 14:05:31
【问题描述】:

两个模型:帖子和作者
此视图显示每个作者的最后一篇文章(作者是 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'))

解决方案

必须在查询集的开头设置排序:

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'))

【问题讨论】:

  • 需要注意的是,Post的日期通常是按id递增的,这样比较容易。 - 你想关闭似乎也可以解决的your older question 吗?

标签: django django-orm


【解决方案1】:

更准确地说,排序应该应用于主查询,而不是子查询。

我更喜欢过滤后的排序,这只是一个见仁见智的问题。

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 是在主查询中还是在子查询中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多