3

我有一个ListView分页:

class StoriesListView(ListView):
    model = Story
    paginate_by = 20

    def get_queryset(self):
        return Story.objects.all().order_by('-updated_at')

Story在数据库中有 1000 个对象。当用户加载我的视图时会发生什么?是从数据库中查询全部 1000 个还是仅查询 20 个?我该如何优化呢?

4

4 回答 4

5

it's depend how you are using it. QuerySet objects are lazy, and in this particular case the sql query will add LIMIT and OFFSET, so the query will always return only 20 results. But when you want using for example related objects in your template, you have to optimize your query with select_related or prefetch_related methods.

I think you should read how to optimize database access in django framework.

Hope this helps.

于 2013-10-12T10:36:23.947 回答
3

该类Paginator获取(即本例中的整个查询集)的返回值get_queryset并将其拼接以使您只能访问 20。它需要对整个查询集进行操作,否则您将无法使用它来显示列表页面例如。

您可以按照代码查看它的实际效果:

get() > get_context_data() > paginate_queryset() > Paginator.init()

这意味着在您的模板上下文中queryset变量是整个查询集。该page变量用于仅获取属于当前页面的那些对象。这是通过拼接初始查询集来完成的,该查询集将评估它并命中数据库。您可以遍历该页面中的对象:{% 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-12T10:37:05.567 回答
0

它只会得到 20 个对象。Paginator 将get_queryset方法的结果作为起始查询集,它只会在迭代时访问数据库,所以你很好。get_queryset方法不会命中数据库本身。

于 2013-10-12T10:34:48.190 回答
-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
于 2013-10-12T11:15:57.970 回答