2009-11-25 63 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

相关问题