2009-05-10 9 views
5

私はDjangoに奇妙な問題があります。私はあなたが通常どおりテンプレート内でループするオブジェクトのセットを持っています。しかし、私は3つのアイテムをグループ化する必要があります。ページのレイアウトは次のように進む:Djangoテンプレート:3つのグループ項目

1絵画 - 2絵画 - 絵画4絵画3

説明1
DESCRIPTION 2
DESCRIPTION 3

- 絵画 - 5絵画6

説明4
説明5
DES C R I P T I O N 6

などなど

私はかなり本当にこれを行うにはDjangoのタグの最良のセットを把握傾けます。ややこしい。 {%cycle%}のステートメントはあまり役に立ちませんでした。

もちろん、私はいくつかの種類のJavaスクリプトのハッキングを行い、Djangoをこのままにしておきますか? 「すべての記述divを後に置く」などの言葉が必要です。この注文をどのように再生するのがベストかわからない何かご意見は?乾杯。

答えて

5

複雑なコードをテンプレート内で試してみると、他の場所。コードをビュー関数に移す代替ソリューションの1つが既に提案されています。

もう1つの解決策は、新しいテンプレートタグを使用して機能を公開することです。ビューソリューションでこのソリューションを選択する理由の1つは、さまざまなビューで表示されるページのコードを簡単に再利用できることです。テンプレートコードで

class GroupPaintingsNode(template.Node): 
    def __init__(self, num, varname): 
     self.num, self.varname = int(num), varname 

    def render(self, context): 
     paintings = Painting.objects.all # do your fetching/filtering here.. 
     l = [[] for i in range(len(paintings))] 
     i = 0 
     while i < len(paintings): 
      l[i].append([p.title for p in paintings[i:i+self.num]]) 
      l[i].append([p.desc for p in paintings[i:i+self.num]]) 
      i += self.num 
     context[self.varname] = l 
     return '' 

def group_paintings(parser, token): 
    tokens = token.contents.split() 
    if len(tokens) != 4: 
     raise template.TemplateSyntaxError, "'%s' tag requires three arguments" % tokens[0] 
    if tokens[2] != 'as': 
     raise template.TemplateSyntaxError, "Second argument to '%s' tag must be 'as'" % tokens[0] 
    return GroupPaintingsNode(tokens[1], tokens[3]) 
group_paintings = register.tag(group_paintings) 

あなたはこのようにそれを使用します。

{% group_paintings 3 as paintings %} 
{% for p in paintings %} 
    {% for title in p.0 %} {{ title }} {% endfor %}<br> 
    {% for desc in p.1 %} {{ desc }} {% endfor %} 
{% endfor %} 
+0

私は、これが最良のテンプレートタグなどと思われるこの機能はとして行くための素敵な場所だと思いますより厄介な見方に反対する。そこにたくさんのリストがありますが、私はそれを得る:)幾分エレガントなソリューションがあります!ありがとう:) – Oni

5

は、どのように、これらの線の周りに何かについてです:

{% for p in paintingss %} 
    <div class="painting">whatever</div> 
    {% if forloop.counter|divisibleby:"3" %} 
     <br> 
    {% endif %} 
{% endfor %} 

は、これはあなたが善を行うのでしょうか?

3

Yuvalは右の行にありますが、絵のリストを2回繰り返します(1行に3つ)と説明のために1回表示します。これは、テンプレート言語内で達成するのは簡単ではありません。

いくつかのCSSで何かできることがあるかどうかを確認することをお勧めします。名前や説明divにクラスを割り当てて、名前がすべて一緒に浮かび、その説明が下にブロックとして表示されるようにする必要があります。しかし、まだトリッキーです。

また、リスト内のリストを前処理して、名前と説明を3つのグループに分けることもできます。あなたはこのような構造で終わるしたい:あなたのテンプレートで

painting_list = [] 
counter = 0 
while counter < len(paintings): 
    painting_list.append([p.name for p in paintings[counter:counter+3]) 
    painting_list.append([p.description for p in paintings[counter:counter+3]) 
    counter += 3 

、その後:

[ 
    [name1, name2, name3], 
    [description1, description2, description3], 
    [name4, name5, name6], 
    [description4, description5, description6], 
    ... 
] 

だから、これやってみてください

{% for group in painting_list %} 
    <div class="names">{% for name in group.0 %}{{ name }} {% endfor %}</div> 

    <ul class="descriptions"> 
     {% for description in group.1 %} 
     <li>{{ description }}</li> 
     {% endfor %} 
    </ul> 
{% endfor %} 
2

を、私は間違いなく構造を作成するための投票しますあなたのビューでは、正しいフォームでテンプレートに渡します。

あなた自身がテンプレートロジックに苦労していることが分かったら、それはあなたのビューでもっと仕事をしているはずのサインです。 (これは私のビューロジックのかなりの部分が私のモデルに戻される必要があることを教えてくれました...)

0
{% for painting in painting_list %} 
    <div class="painting">{{ painting }}</div> 
    {% if forloop.counter|divisibleby:"3" %} 
     <br> 
     {{ description_list.forloop.counter0-2 }} 
     {{ description_list.forloop.counter0-1 }} 
     {{ description_list.forloop.counter0 }} 
    {% endif %} 
{% endfor %} 

ちょうどので、あなたは、このコードは動作しません知っているが、このようなものは、あなたが望むものです。

多分、オブジェクトリストのn番目のオブジェクトにアクセスするために独自のtemplatetagを用意することができます。

5

あなたはこのために単純なフィルタを使用することができます。

import itertools 

from django import template 

register = template.Library() 

@register.filter 
def chunks(value, chunk_length): 
    """ 
    Breaks a list up into a list of lists of size <chunk_length> 
    """ 
    clen = int(chunk_length) 
    i = iter(value) 
    while True: 
     chunk = list(itertools.islice(i, clen)) 
     if chunk: 
      yield chunk 
     else: 
      break 

は、その後、あなたのテンプレートの内側:

{% for chunk in paintings|chunks:3 %} 
    <div class="row"> 
    {% for painting in chunk %} 
     <div>{{ painting }}</div> 
    {% endfor %} 
    </div> 
{% endfor %} 
関連する問題