2017-01-08 29 views
1

在一類基於Django的listview,當一個下發的一個值paginate_by,它確保object_list提供get_context_data方法侷限於只有那些需要的對象該特定頁面優化在基於功能的視圖(在Django)分頁

E.g. get_queryset可能會返回1000個對象,但是如果單個頁面顯示20個對象,則只有20個對象可用,其中object_list位於get_context_data。處理大型查詢集時這是一個很好的優化。

如何在基於函數的視圖中創建相同的行爲?在典型的實現(並採取上述示例)下,所有1000個對象將被評估,然後用於分頁。這意味着在這種特殊情況下,CBV明顯優於基於功能的視圖。基於功能的視圖可以提供相同的功能嗎?一個說明性的例子會很棒(或者是「不,他們不能」)。


這裏的實際CBV:

class PostListView(ListView): 
    model = Post 
    paginate_by = 20 
    template_name = "post_list.html" 

    def get_queryset(self): 
     return all_posts() 

    def get_context_data(self, **kwargs): 
     context = super(PostListView, self).get_context_data(**kwargs) 
     posts = retrieve_posts(context["object_list"]) #retrieves 20 posts 
     return context 

這裏的實際FBV:

def post_list(request, *args, **kwargs): 
    form = PostListForm() 
    context = {} 
    obj_list = all_posts() 
    posts = retrieve_posts(obj_list) #retrieves 1000 posts 
    paginator = Paginator(posts, 20) 
    page = request.GET.get('page', '1') 
    try: 
     page = paginator.page(page) 
    except PageNotAnInteger: 
     page = paginator.page(1) 
    except EmptyPage: 
     page = paginator.page(paginator.num_pages) 

retrieve_posts()功能:

def retrieve_posts(post_id_list): 
    my_server = redis.Redis(connection_pool=POOL) 
    posts = [] 
    pipeline1 = my_server.pipeline() 
    for post_id in post_id_list: 
     hash_name="pt:"+str(post_id) 
     pipeline1.hgetall(hash_name) 
    result1 = pipeline1.execute() 
    count = 0 
    for hash_obj in result1: 
     posts.append(hash_obj) 
     count += 1 
    return posts 

all_posts()功能:

def all_posts(): 
    my_server = redis.Redis(connection_pool=POOL) 
    return my_server.lrange("posts:1000", 0, -1) #list of ids of 1000 posts 

差異的兩種方法(通過NewRelic的)的響應時間:

enter image description here

藍色部分是視圖的處理。

+0

哈桑你好,你似乎有這個看法是正確的。什麼似乎是問題? – e4c5

+0

嘿@ e4c5。我檢索的對象是redis哈希。在基於類的視圖中,上下文被限制爲20個對象(感謝'paginate_by'),而在FBV中,我最終執行整個1000個對象列表的檢索。因此,與CBV相比,服務器響應時間是我的FBV的兩倍。 –

+0

你可以把兩個methodos的絕對時間,並張貼retrieve_object_list方法 – e4c5

回答

2

不要用原始對象列表調用retreive_posts。分頁後使用頁面的對象列表。

posts = retrieve_posts(page.obj_list) 
+0

大事情有小的開始。感謝這個見解。 –

相關問題