限制 Django 查询集返回的结果集的方法是通过数组切片完成的。例如获取前5个人:
People.objects.all()[0:5]
或者,让它们按名称排序:
People.objects.order_by(name)[0:5]
或按姓名排序,但仅限 65 岁以上的人:
People.objects.order_by(name).filter(age__gt=65)[0:5]
事实上,我能想到的唯一在查询集上没有函数的事件是有限的。
我想知道的是,是否有一种方法(内部的、文档化的或其他方式)可以在充当限制或切片的 QuerySet 上调用? 如果不是,执行此操作的最佳方法是什么?
注意事项:
- 是的,这可能是个坏主意,不,我不太热衷于实现它,但如果有一个很好的理由来完成它,可以吗?
- 是的,我知道切片是延迟执行的,这不是我要问的。
- This is not a duplicate of this question ,正如公认的答案所说:
Do
results[:max_count]in a view, after.order_by().
请您参考如下方法:
查看 Django Querysets, its not as blackboxy 的代码看起来
def __getitem__(self, k):
"""
Retrieves an item or slice from the set of results.
"""
# ... trimmed ...
if isinstance(k, slice):
qs = self._clone()
if k.start is not None:
start = int(k.start)
else:
start = None
if k.stop is not None:
stop = int(k.stop)
else:
stop = None
qs.query.set_limits(start, stop)
return list(qs)[::k.step] if k.step else qs
qs = self._clone()
qs.query.set_limits(k, k + 1)
return list(qs)[0]
关键行在这里:
qs.query.set_limits(start, stop)
slice 是惰性的原因是因为它只接受 start 和 stop 值并将它们传递给另一个方法。
Which corresponds to a call to the sql.Query object here:
def set_limits(self, low=None, high=None):
因此可以(尽管可能不推荐)像这样对查询集进行切片:
people = People.objects.order_by(name).filter(age__gt=65) # unevaluated
people.query.set_limits(start, stop) # still unevaluated
for person in people: # now its evaluated
person.do_the_thing()
