使用render_to_response的Django性能

时间:2017-09-13 02:42:19

标签: python django performance templates

我有Django app,它有以下声明:

java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Java heap space (failed to allocate 3997712 bytes)
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at test.app.TestApp.main ....

template.html上的典型陈述是:

    response = render_to_response('template.html', {'s':s, 'r':r}, context_instance=RequestContext(request))

大约有10万条记录。页面响应时间大约需要3分钟(ThinkServer,Linux,Apache,mod_wsgi,Python3.4,Django 1.9.4,MySQL),这是正常的吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

每次调用{{ m.XXX.id }}都会导致XXX实例的单独SQL查询。为避免这种情况,您应该使用查询集的select_related()方法。

将以下方法添加到r变量的类中:

def get_all_m(self):
    return self.m_set.all().select_related()

然后在模板中使用它:

{% for m in r.get_all_m %}

答案 1 :(得分:0)

要仅访问相关模型的ID,请将_id后缀添加到字段名称中。此数据已经可用,因为它是外键的值,因此您不需要额外的查询或连接。但是,您正在访问Name字段的StorageLocation属性,因此您需要一个联接来阻止在每次迭代中执行查询。

您对数据的要求变为:

r.m_set.select_related('StorageLocation').all()

您的模板变为:

<tbody>
{%for m in r.m_set.all %}
  <tr>
    <td>{{m.id}}</td>
    <td>{{m.Name}}</td>
    <td>{{m.MaterialLot_id}}</td>
    <td>{{m.MaterialSublot_id}}</td>
    <td>{{m.Description|truncatechars:20}}</td>
    <td>{{m.StorageLocation.id}} - {{m.StorageLocation.Name}}</td>
    <td>{{m.Quantity|floatformat:"-3"}}</td>
    <td>{{m.QuantityUnitOfMeasure_id}}</td>
    <td>{{m.Status_id}}</td>
  </tr>  
{%endfor%}
</tbody>

请记住,如果您需要访问相关模型上id以外的字段,请将字段名称添加到select_related()来电。