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
相关产品推荐
相关产品推荐

