2017-09-13 64 views
0

我有Django應用程序,已下面的語句:Django的性能選擇render_to_response與

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

的典型發言在template.html是:

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

大約有10數以千計的記錄。頁面響應時間大約需要3分鐘(ThinkServer,Linux,Apache,mod_wsgi,Python3.4,Django 1.9.4,MySQL),這是正常的嗎?

謝謝!

+1

張貼您的模特。它在我看來像你在循環的每次迭代中進行查詢,這將解釋爲什麼它很慢。 – mindcruzer

回答

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 %} 
+0

'select_related()'對於每個相關的模型都是不必要的 - 它只需要'StorageLocation'字段。外鍵的值可以用於其他值。 – mindcruzer

0

只能訪問相關模型的ID,加_id後綴爲字段名稱。此數據已可用,因爲這是外鍵的值,所以您不需要額外的查詢或連接。但是,您訪問StorageLocation字段的Name屬性,因此您需要聯接以防止在每次迭代中執行查詢。

您的通話將數據變爲:

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()