我以前用过一些django分页的代码示例。我可能错了,但是当我检查代码时,它看起来像是在浪费大量的内存。我在寻找更好的解决方案,下面是代码:
# in views.py
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
...
...
def someView():
models = Model.objects.order_by('-timestamp')
paginator = Paginator(models, 7)
pageNumber = request.GET.get('page')
try:
paginatedPage = paginator.page(pageNumber)
except PageNotAnInteger:
pageNumber = 1
except EmptyPage:
pageNumber = paginator.num_pages
models = paginator.page(pageNumber)
return render_to_resp ( ..... models ....)
我不确定这段代码的子部分,但从它的外观来看,第一行代码从数据库中检索每个模型并将其推入。然后它被传递到Paginator中,Paginator根据用户从html获取的页面将其分块。paginator是否可以接受这一点,或者这完全是内存不足?如果效率低下,如何改进?
还有一个相关的话题。如果有人这样做:
Model.objects.all()[:40]
这段代码是不是意味着所有的模型都被推入内存,而我们将其中的40个拼接出来?这很糟糕。或者这是否意味着我们只查询并将40个对象推入内存周期?
谢谢你的帮助!
利用上面的信息,我想出了一个视图函数decorator。json_list_对象将djanog对象带到django对象的已知关系字段的json-ready python指令,并将jsonified列表返回为{count:results:}。
其他人可能会觉得它有用。
mymodel.objects.all()
生成查询集,而不是列表。Querysets是惰性的—在您真正尝试使用它们之前,不会发出任何请求,也不会执行任何操作。同时,切片查询集并不会只为了得到一个子集而在内存中加载整个该死的东西,而是在命中数据库之前向SQL查询添加限制和偏移量。使用paginator时没有内存效率低下的问题。对查询集的评估很懒。在您的调用
Paginator(models, 7)
中,models
是一个直到现在才被计算的queryset。所以,到目前为止数据库还没有被击中。此时内存中也没有包含模型的所有实例的列表。当您想要获得一个页面,即在
paginatedPage = paginator.page(pageNumber)
时,将在此queryset上执行切片,此时数据库将被命中,数据库将返回一个queryset,其中包含model的实例。然后切片只返回页面上应该存在的对象。所以,只有被切片的对象才会出现在内存中的列表中。假设在一个页面上你想显示10个对象,只有这10个对象会留在内存中。当有人这样做时
切片列表时,将创建一个新列表。在您的情况下,将创建一个只有40个元素的列表,并将其存储在内存中的某个位置。不会有其他列表,因此不会有任何列表包含内存中
Model
的所有实例。相关问题 更多 >
编程相关推荐