2009-11-25 2 views
2

데이터 테이블을 표시하기 위해 루핑 할 큰 데이터 집합이 있습니다. 문제는 반복하는 데 시간이 많이 걸리는데, 이것은 내부 도구이므로 현재로서는 괜찮습니다.하지만 개선하고 싶습니다.장고 템플릿에서 여러 목록을 반복하는 더 좋은 방법

모델 :

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

+0

보기와 함께 업데이트 됨 : –

+0

이 태그를 호출하는 템플릿도 함께 표시하십시오. –

답변

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

참고 : 이것은 코드에서보다 많은 데이터베이스 쿼리를 생성합니다 ('metric' /'date' 조합 당 하나). 너무 많은 오버 헤드가 발생하면 모든 데이터를 가져 와서 논리적 그룹화를 직접 계산할 수 있습니다. –

0

보기가 느린 경우 문제는 데이터베이스에있는 경우가 많습니다. 데이터베이스에 어떤 쿼리가 사용되는지 알고 있습니까? db 트래픽을 크게 줄이는 작은 변화를 만들 수 있습니다.

+0

보기로 업데이트 됨 : –

0

비슷한 문제를 암시하는 것처럼 보이는이 블로그 게시물을 발견했습니다. 사용

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

는 "| 안전"내 모든 변수에이 문제에 대한 경우 다른 사람 비틀 거림 적어도 뭔가 ...

게시되는 반 내로드 시간을 잘라.

+1

무차별로 사용하기 전에 '안전함'이 무엇인지 이해했는지 확인하십시오. –

관련 문제