2011-05-18 56 views
3

我一直在爲這個問題摔角至少兩天。 有一個視圖會生成一個頁面,顯示某個用戶/電話分機所做的所有電話呼叫。沒有什麼奇特的,只有很長的一頁,最多1000行。Django - 生產中特定視圖的等待時間需要很長的時間

此視圖函數從url中接收一些參數,以便選擇要在此頁面上顯示的內容。有兩種情況,一個地方的「延長= XXXXXX」傳遞和一個其中「user = XXXX」中的URL傳遞:

if request.GET.get("extension", None): 
    # extension_query expects only one Extension object 
    extension_query = Extension.objects.filter(number=request.GET["extension"]) 
    ... # Here I do some conditionals to match the right Extension object. 
elif request.GET.get("user", None): 
    ... # Simple stuff, nothing to significant. 
# at the end I call render_to_response normally 

編輯 - 這是一段調用我的自定義選擇render_to_response代碼:
EDIT2 - 迫使查詢集的評價約翰·C·的建議後,加載時間從1.6分鐘減少到14秒:

if (request.GET.get("format", None) == "screen" 
    or request.GET.get("print", False)): 
    ctx = dict(calls=list(calls), client=client, extension=extension, 
       no_owner_extension=no_owner_extension, 
       start=start_date, end=end_date, tab="clients", 
       owner=user) 
    return finish_request(
     request, "reports/exporting_by_call_type.html", ctx) 
:現在我把它傳遞給我的定製選擇render_to_response前投我的調用列表()

這是我定製的render_to_response:

def finish_request(request, template, context): 
    if "print" in request.GET or "print" in request.POST: 
     context.update(printing=True) 
    return render_to_response(
     template, RequestContext(request, context)) 

在我的機器,它需要3-4秒,根據Chrome的審計工作BOTH情況完全處理這一觀點的現實數據的情況。在生產中,加載視圖的時間需要3-4秒,其中用戶參數在URL中傳遞,但當擴展通過時,需要2分鐘!

編輯:這說的是,在URL傳球用戶擴展之間的區別並不在頂部,因爲當分機號碼屬於別人的,我表示改變最終呈現的頁面,除了一條線是非常重要的。其餘的數據是完全一樣的。

我在我的代碼中描述了生成這個視圖的每個小塊。我計算了視圖在我的生產代碼中需要多長時間render_to_response(0.05秒)。我拿出分機的部分在我的模板中被調用但沒有成功。我還使用django_debug_toolbar查看每個SQL語句正在做什麼,最多隻需2秒。

我還要補充一點,我使用的mod_wsgi,調試=我的製作設置假 ... YSlow的利率這個頁面94儘管採取2分鐘。

任何人都可以點亮一下嗎?

+0

小調 - 在瀏覽Django文檔時,我注意到[repr()](https://docs.djangoproject.com/en/1.3/ref/models/querysets/#when-querysets-are - 評估)Queryset函數,它強制對查詢集進行評估,但是*沒有*將它變成列表。在你(或某人)不希望*列表*,但仍然想要強制對查詢集進行評估的情況下,這是一個選項。 – 2011-08-24 20:14:20

回答

2

我沒有看到任何明顯錯誤的代碼。我有一個問題,是你期待完全匹配一個對象嗎?如果是的話,可能會嘗試這種代碼是值得的:

getData = request.GET.copy() # optional, I like my own copy. 
if 'extension' in getData: 
    ext = getData['extension'] 
    extObj = Extension.objects.get(number__exact=ext) # double-underline 
# elif... 

注意,將導致擴展對象,而不是一個查詢集。如果你有多個擴展名,那麼你就需要使用過濾 - 但我還是建議使用確切,以及EXT的讀數從字典中移動,到過濾聲明之外。

更新(從我的評論) - 嘗試強制使用對list()的調用立即評估Queryset,看看它是否對render_to_response有影響。

更新2 - 因爲它沒有有效果 - 這是我認爲可能會發生。由於Django Querysets使用延遲評估,當模板最終執行時 - 它調用一個迭代器,而不是現有的列表。也許有太多的函數調用正在進行,每次調用迭代器以獲得新的值,都會產生大量不必要的開銷。或者也許有一個錯誤。 :)

+0

我期待完全匹配一個擴展對象。實際上,一旦我獲得「extension_query」以匹配正確的擴展名,我就會多做一點。讓我感到不安的是,我確信我的整個功能需要很長時間才能完成處理。這是render_to_response之後發生的事情,需要很長時間。 – chiurox 2011-05-18 20:36:58

+0

@chiurox,也許值得將render_to_response代碼添加到您的帖子中?另外 - 它可能是值得嘗試強制查詢集立即評估,說[len()或list()](http://docs.djangoproject.com/en/1.2/ref/models/querysets/#when -querysets-are-evaluate) - 查看對render_to_response有什麼影響。 – 2011-05-18 20:58:38

+0

好吧,我用list()來強制queryset被評估。它「神奇地」將加載時間從大約2分鐘減少到15秒。看我的編輯。 – chiurox 2011-05-18 22:03:09