2013-10-12 41 views
3

我有一個ListView與分頁:Django的:分頁的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個?我怎樣才能優化這個?

回答

5

這取決於你如何使用它。 QuerySet對象是lazy,在這種特殊情況下,sql查詢將添加LIMITOFFSET,因此查詢將始終只返回20個結果。但是,如果要在模板中使用相關對象,則必須使用select_relatedprefetch_related方法優化查詢。

我想你應該看看如何在django框架中使用optimize database access

希望這會有所幫助。

0

它只會得到20個對象。 Paginator將get_queryset方法的結果作爲啓動queryset,並且只在迭代時纔會觸發數據庫,​​所以您很好。 get_queryset方法不會打到數據庫本身。

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] 
-3

同樣的問題,我的分頁中已經取出。 對於分頁你不需要使模態內的函數。

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 

可以使用LIMT相同想到可以通過簡單的我的期廣義函數

高清testPagination(請求)完成