2009-11-25 28 views
2

我有一些大的數據集,我循環顯示數據表。麻煩在於循環需要花費大量的時間,這是正確的,因爲這是一個內部工具,但我想改進它。更好的方式來循環瀏覽Django模板中的多個列表

型號:

class Metric_Data(models.Model): 
    metric = models.ForeignKey(Metric) 
    count = models.IntegerField() 
    start_date = models.DateField() 

我顯示錶,其中的第一列是日期,那麼每個以下列列出該日期的計數的度量。像這樣:

Dates Metric Metric Metric ... 
10/11  10  11  12 
11/11  22 100 1000 
...  ... ... ... 

我試圖循環遍歷視圖中的數據,並創建表得到的名單,並通過這種對模板進行渲染,但有幾個指標上千個數據點每公噸,這是相當緩慢的。因爲我已經切換到模板標籤:

def getIndex(parser, token): 
    try: 
    tag_name, a_list, index = token.split_contents() 
    except ValueError: 
    raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0] 
    return GetIndexNode(a_list, index) 

class GetIndexNode(template.Node): 
    def __init__(self, a_list, index): 
    self.the_list = template.Variable(a_list) 
    self.index = template.Variable(index) 

    def render(self, context): 
    try: 
     the_list = self.the_list.resolve(context) 
     i = self.index.resolve(context) 
     return the_list[i] 
    except template.VariableDoesNotExist: 
     return '' 

這仍然是相當緩慢的,這只是可能,因爲這是我第一次寫一個模板標籤,我做錯了什麼。

編輯:

def show_all(request): 
    metrics = Metric.objects.all() 
    dates = Metric_Data.objects.all().values_list('start_date',flat=True).distinct().order_by('start_date') 

    data = [] 

    for metric in metrics: 
    data.append(Metric_Data.objects.filter(metric=metric).order_by('start_date').values_list('count', flat=True)) 

    return render_to_response('metric/show_all.html', {'dates': dates, 
                'metrics': metrics, 
                'data': data}) 

編輯:和模板

<table id="theTable" class="paginate-5"> 
<thead> 
<tr> 
<th>Dates</th> 
    {% for metric in metrics %} 
     <th>{{ metric.name }}</th> 
    {% endfor %} 
</tr> 
</thead> 
<tbody> 
{% for date in dates %} 
    <tr> 
    <td>{{date}}</td> 
    {% for metric in data %} 
     <td>{% get_index metric forloop.parentloop.counter0 %}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
</tbody> 

我想最好的地方我在像這樣的視圖獲取數據解決這個問題可能在模型中,但我不知道如何去解決這個問題。可能爲日期創建一個表並在該表上執行查詢?

想法非常感謝謝謝!

+0

如何從數據庫中提取數據? – Kugel 2009-11-25 02:10:05

+0

更新視圖:) – 2009-11-25 02:49:14

+0

請同時顯示調用此標籤的模板。 – 2009-11-25 12:16:23

回答

1

我認爲你只是對你的數據進行嚴重的分組,這樣你最終會在相同的項目上多次循環,產生非常差的複雜度。儘量將數據結構與模板中使用的方式非常接近。

例如:

def metric_count_on (metric, date): 
    return Metric_Data.objects.filter(metric=metric,start_date=date).values_list('count',flat=True) 
def show_all(request): 
    metrics = Metric.objects.all() 
    dates = Metric_Data.objects.all().values_list('start_date',flat=True).distinct().order_by('start_date') 
    # generate full report. now, template only has to loop. 
    data = [{'date':date, 'metrics':metric_count_on(date, metric)} 
     for (date,metric) in itertools.product(dates,metrics)] 
    # ... 

然後,在模板中,你可以基本上只是環路:

{% for row in data %} 
    <tr> 
    <td>{{ row.date }}</td> 
    {% for count in row.metrics %} 
     <td>{{ count }}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
+0

注意:這將產生比您的代碼更多的數據庫查詢(每個「度量」/「日期」組合)。如果這是太多的開銷,您可能想要獲取所有數據並自行計算邏輯分組。 – 2011-05-01 06:34:22

0

如果您發現視圖變慢,則問題通常出現在數據庫中。你確定你知道什麼查詢要進入數據庫嗎?有可能你可以做一個小改動,這會大大減少數據庫流量。

+0

更新了視圖:) – 2009-11-25 02:49:54

0

我發現這篇博文似乎暗示類似的問題。

http://www.xorad.com/blog/?p=1497

使用「|安全」在我所有的變量把我的加載時間減半其中至少一些信息

發帖萬一別人絆倒這個問題。

+1

請確保您明白什麼'安全'是在不加選擇地使用它之前。 – 2011-05-23 09:44:07