You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中get_queryset内limit查询不生效问题咨询

问题现象

重写get_queryset方法后,尝试对父类返回的QuerySet做排序和切片限制,发现切片未生效:

def get_queryset(self, request):
    qs = super().get_queryset(request)
    qs.order_by('-id').all()[:3]
    print(qs)
    print()

    qs2 = CreditsTransaction.objects.all()[:3]
    print(qs2)
    return qs

输出结果:

[2023-04-19 08:53:52 +0000] [1178] [INFO] Booting worker with pid: 1178
<QuerySet [<CreditsTransaction: CreditsTransaction object (623267)>, <CreditsTransaction: CreditsTransaction object (623266)>, <CreditsTransaction: CreditsTransaction object (623265)>, <CreditsTransaction: CreditsTransaction object (623264)>, <CreditsTransaction: CreditsTransaction object (623263)>, '...(remaining elements truncated)...']>

<QuerySet [<CreditsTransaction: CreditsTransaction object (623267)>, <CreditsTransaction: CreditsTransaction object (623266)>, <CreditsTransaction: CreditsTransaction object (623265)>]>

可见qs.order_by('-id').all()[:3]没有将结果限制为3条,而直接调用CreditsTransaction.objects.all()[:3]可以正常生效。

原因分析

Django的QuerySet具有不可变性:对QuerySet调用order_by()、切片等方法时,不会修改原QuerySet对象,而是返回一个全新的QuerySet实例。

你的代码中,qs.order_by('-id').all()[:3]只是生成了一个经过排序和切片的新QuerySet,但没有将这个新对象赋值回qs变量,所以原来的qs还是父类返回的完整QuerySet,自然输出和返回的都是未被限制的结果。

而qs2 = CreditsTransaction.objects.all()[:3]是直接将切片后的新QuerySet赋值给了qs2,所以输出的是正确的3条数据。

修正方法

将排序和切片后的新QuerySet重新赋值给qs即可:

def get_queryset(self, request):
    qs = super().get_queryset(request)
    qs = qs.order_by('-id')[:3]  # all()方法可省略,因为qs本身就是QuerySet
    print(qs)
    print()

    qs2 = CreditsTransaction.objects.all()[:3]
    print(qs2)
    return qs

内容的提问来源于stack exchange,提问作者Harm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:27:49