在django模板中循环多个列表的更好方法

在django模板中循环多个列表的更好方法,django,Django,我有一些大数据集,我正在循环显示一个数据表。问题是循环需要花费大量的时间,这在目前还可以,因为这是一个内部工具,但我想改进它 模型: class Metric_Data(models.Model): metric = models.ForeignKey(Metric) count = models.IntegerField() start_date = models.DateField() 我正在显示一个表,其中第一列是日期,接下来的每列都是一个指标,列出了该日期的计数。像这样:

我有一些大数据集,我正在循环显示一个数据表。问题是循环需要花费大量的时间,这在目前还可以,因为这是一个内部工具,但我想改进它

模型:

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>

日期
{度量%中度量的%s}
{{metric.name}
{%endfor%}
{日期百分比中的日期为%}
{{date}}
{数据%中的度量值为%}
{%get_索引度量forloop.parentloop.counter0%}
{%endfor%}
{%endfor%}

我认为解决这个问题的最佳方法可能是在模型中,但我不确定如何解决。为日期创建一个表,并对该表进行查询


非常感谢

如果您发现自己的视图速度慢,问题往往出在数据库中。您确定知道要对数据库进行哪些查询吗?你可以做一个小改动,大大减少数据库流量。

我发现这篇博文似乎暗示了类似的问题

在所有变量上使用“| safe”将我的加载时间减少一半,这至少是


以防其他人遇到此问题时发布。

我认为您只是对数据进行了错误的分组,从而导致在同一项目上循环多次,从而导致非常低的复杂性。尽量按照模板中使用数据的方式来组织数据

例如:

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 %}
{%用于数据%中的行]
{{row.date}
{row.metrics%中的计数为%1}
{{count}}
{%endfor%}
{%endfor%}

如何从数据库中获取数据?请同时显示调用此标记的模板。注意:这将产生比代码中多得多的数据库查询(每个
度量值
/
日期
组合一个)。如果开销太大,您可能希望自己获取所有数据并计算逻辑分组。在不加区别地使用它之前,请确保您了解
safe
的用途。