我有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?我该如何优化呢?
答案 0 :(得分:5)
这取决于你如何使用它。 QuerySet对象是lazy,在这种特殊情况下,sql查询将添加LIMIT
和OFFSET
,因此查询将始终只返回20个结果。但是,当您希望在模板中使用相关对象时,必须使用select_related
或prefetch_related
方法优化查询。
我认为你应该阅读django框架中optimize database access的方法。
希望这有帮助。
答案 1 :(得分:2)
Paginator
类获取get_queryset
的返回值(在这种情况下是整个查询集)并拼接它以使您只能访问20.它需要对整个查询集进行操作,否则你例如,将无法使用它来显示页面列表。
您可以看到关注代码以查看其实际效果:
get()> get_context_data()> paginate_queryset()> Paginator.init()
这意味着in your template context,queryset
变量是整个查询集。 page
变量用于仅获取属于当前页面的那些对象。这是由splicing the initial queryset完成的,它将对其进行评估并点击数据库。您可以遍历该页面中的对象:{% 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]
答案 2 :(得分:0)
它只会获得20个物体。 Paginator将get_queryset
方法的结果作为起始查询集,它只会在迭代时命中数据库,所以你很好。 get_queryset
方法没有点击数据库本身。
答案 3 :(得分:-3)
我在分页期间遇到的同样问题。 对于分页,您不需要在模态中创建函数。
你可以使用LIMT,通过简单的我的通用功能可以做到这一点
def testPagination(请求):
dataObj = paginationData('Item',page_no,10)
data["dataIndex"] = dataObj["dataIndex"]
data["page_no"] = dataObj["page_no"] #given page number will helps to active link at template
data["data"] = dataObj["data"] #actual data will helps in template
data['pagination'] = dataObj["pagination"] #Will helps to make dynamic link for pagination
def paginationData(modalName,pageNo,perPage):
data = {} #initialize variables
Modal = getModel(modalName) # Function to get modal reference
count = Modal.objects.count()#Calculate no of records
no_of_record_per_page = ceil(float(count) / perPage)
print ",Records counts : " + str(no_of_record_per_page)
pages = [] #No of pages
pages.append(1)
a = 1
while a < (no_of_record_per_page):
a += 1 # Same as a = a + 1
pages.append(a)
data["pagination"] = pages # pagenation for display link of page
data["page_no"] = pageNo
data['data'] = Modal.objects.all()[((pageNo-1)*perPage):(pageNo*perPage)]
data['dataIndex'] = str((pageNo -1)*perPage)
return data