我有一个带有分页的ListView
:
class StoriesListView(ListView):
model = Story
paginate_by = 20
def get_queryset(self):
return Story.objects.all().order_by('-updated_at')
我在数据库中有1000个Story
对象。当用户加载我的视图时会发生什么?是从数据库中查询所有的1000条,还是只查询20条?我怎么才能优化这个?
发布于 2013-10-12 10:36:23
发布于 2013-10-12 10:37:05
Paginator
类接受get_queryset
的返回值(在本例中为整个查询集),并将其连接起来,使您只访问20个查询集。它需要对整个查询集进行操作,否则您将无法使用它来显示页面列表。
您可以看到,按照代码来查看它的运行情况:
得到() > 数据() > queryset() > Paginator.init()
这意味着在模板上下文中,queryset
变量是整个查询集。page
变量仅用于获取属于当前页的对象。这是由拼接初始查询集完成的,它将对其进行评估并命中DB。您可以遍历页面中的对象:{% for object in page %}
,这样就不会再次访问数据库了:
# https://github.com/django/django/blob/master/django/core/paginator.py#L119
def __getitem__(self, index):
if not isinstance(index, (slice,) + six.integer_types):
raise TypeError
# The object_list is converted to a list so that if it was a QuerySet
# it won't be a database hit per __getitem__.
if not isinstance(self.object_list, list):
self.object_list = list(self.object_list)
return self.object_list[index]
发布于 2013-10-12 10:34:48
它只会得到20个物体。分页器将get_queryset
方法的结果作为开始查询集,并且只有在迭代时才会访问数据库,所以您很好。get_queryset
方法不访问数据库本身。
https://stackoverflow.com/questions/19333102
复制相似问题