2011-05-18 115 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