【问题标题】:Slice queryset after order_by() in Django在 Django 中的 order_by() 之后切片查询集
【发布时间】:2023-01-22 06:07:41
【问题描述】:

我有 order_by() 模型 django 并得到查询集以下结果:

queryset = <QuerySet [<MyModel: MyModel object (4)>, <MyModel: MyModel object (2)>, 
<MyModel: MyModel object (1)>, <MyModel: MyModel object (3)>, <MyModel: MyModel object (5)>]>

结果未按 id 排序。

我想要具有订单 MyModelid greater than 1 的切片查询集以获得以下结果:

new_queryset = <QuerySet [<MyModel: MyModel object (4)>, <MyModel: MyModel object (2)>]>

有没有办法像这样在没有循环的情况下进行切片以减少查询?

for index in range(len(queryset)):
    if queryset[index].id == 1:
        new_queryset = queryset[:index]
        break

【问题讨论】:

  • 您的查询集中的默认顺序是什么?
  • 我有 2 个关于 order_by 的日期时间字段,如下所示:.order_by(F("publish_datetime").desc(nulls_last=True), "-modified")

标签: python django django-models django-queryset django-orm


【解决方案1】:

假设您正在根据publish_datetimemodified对查询集进行排序,您可以简单地获取具有所需id的记录,并根据与对象相关的排序来过滤查询集,如下所示:

from django.db.models import F, Q

reference_object = MyModel.objects.get(id=1)
queryset = MyModel.objects.filter(
    Q(publish_datetime__lt=reference_object.publish_datetime) |
    Q(
        Q(publish_datetime=reference_object.publish_datetime) &
        Q(modified__gt=reference_object.modified)
    )
)

您将获得在所需对象之前发布帖子的结果,或者发布时间相同但修改日期更近的结果

【讨论】:

    【解决方案2】:

    您可以使用 QuerySetManager 提供的 filterexclude 功能。基本上你可以做到以下几点:

    new_queryset = MyModel.objects.filter(id__gt=1)
    

    【讨论】:

      【解决方案3】:

      您可以对列表结果进行切片,如下所示:

      new_queryset = MyModel.objects.filter(id__gt=1)[:5]
      

      5 表示根据您过滤的查询集只会显示 5 条记录。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-03
        • 1970-01-01
        相关资源
        最近更新 更多