14

こんにちは、Django テンプレートに渡す 2 つの辞書のリストがあります。

base_parts = [
    {'important item': 43},
    {'lesser item': 22, 'lesser item': 3, 'lesser item': 45}
]

私のテンプレートでは、これを行うことができます:

{% for base_part in base_parts %}
    {% for k, v in base_part.items %}

    {# ...do stuff #}

    {# I try to get a running total of items to use as an ID #}
    inner ID: {% forloop.counter0 %}< br/>
    outer ID: {% forloop.parentloop.counter0 %}< br/>

    {% endfor %}
{% endfor %}

ご覧のとおり、繰り返し処理したアイテムの総数の現在の合計が必要ですが、含めた両方の方法で重複が返されます。ループを連結できることはわかっていますが、フォームセットを使用していて、ID に 0、1、2 などのインデックスを付けたいと思っています。

テンプレートでこのタイプのカウントを達成する方法はありますか?

どんな助けでも大歓迎です。

編集

現時点での出力は次のようになります。

outerID: 0<br />
innerID: 0<br />
outerID: 0<br />
innerID: 1<br />
outerID: 1<br />
innerID: 0<br />
outerID: 1<br />
innerID: 1<br />
outerID: 1<br />
innerID: 2<br />

私が欲しい:

totalID: 0<br />
totalID: 1<br />
totalID: 2<br />
totalID: 3<br />
totalID: 4<br />
totalID: 5<br />
totalID: 6<br />
totalID: 7<br />
totalID: 8<br />
totalID: 9<br />
4

5 に答える 5

13

でより良い解決策を見つけましたitertools。(以前の回答よりも優れています)ループの現在の状態を、ビューコンテキストに送信される itertools 変数に設定できます。今回はダミーの Django プロジェクトを試してみましたが、魅力的に動作します。

ビュー.py:

from django.shortcuts import render_to_response
import itertools

def home(request):
    iterator=itertools.count()
    base_parts = [
        {'important item': 43},
        {'lesser item1': 22, 'lesser item2': 3, 'lesser item3': 45},
        {'most important item': 55}
    ]
    return render_to_response('index.html', 
                             {'base_parts': base_parts, 'iterator':iterator})

index.html:

{% for base_part in base_parts %}
    {% for k, v in base_part.items %}
        {{ iterator.next }} - {{ v }}<br/>
    {% endfor %}
{% endfor %}

HTML 出力:

0 - 43
1 - 22
2 - 45
3 - 3
4 - 55

ソートされた値:

(この部分は実際の質問に対する回答ではありません。いじっているようなものです)

Python の組み込み辞書の代わりにDjango のSortedDictを使用して、アイテムの順序を保つことができます。

ビュー.py

from django.shortcuts import render_to_response
import itertools
from django.utils.datastructures import SortedDict

def home(request):
    iterator=itertools.count()
    base_parts = [
        SortedDict([('important item', 43)]),
        SortedDict([('lesser item1', 22), 
                    ('lesser item2', 3), 
                    ('lesser item3', 45)]),
        SortedDict([('most important item', 55)])
    ]
    print base_parts[1]
    return render_to_response('index.html', 
                             {'base_parts': base_parts, 'iterator':iterator})

HTML 出力:

0 - 43
1 - 22
2 - 3
3 - 45
4 - 55

2014 年 5 月 25 日を編集

Django の SortedDict の代わりにcollections.OrderedDictを使用することもできます。

2016 年 6 月 28 日編集

呼び出しiterator.nextは Python 3 では機能しません。 itertools.count から継承して、独自の反復子クラスを作成できます。

import itertools
class TemplateIterator(itertools.count):
    def next(self):
        return next(self)
于 2012-12-14T02:02:04.417 に答える
4

理想的な世界では、この種のロジックをテンプレートに入れないようにする必要があります。出力で階層を保持しない場合 (たとえば、これらの項目をリストのリストとして表示する場合)、リストを平坦化し、単純な for ループとループ カウンターを使用します。

ただし、理想的なソリューションが常に選択肢にあるとは限りません。理論的には、以下が機能する可能性がある/機能するはずだと思います

{% for base_part in base_parts %}     
    {% with outerCount = forloop.parentloop.counter0 %}
    {% for k, v in base_part.items %}
        ...
        {% with innerCounter = forloop.counter %}
        {{ outerCounter|add:innerCounter }}
    {% endfor %}
{% endfor %}
于 2012-12-14T01:38:57.777 に答える
1

更新:これは正解ではありません。動作しないものを表示するために、ここに保持しています。

私はこれを試したことがないことを認めなければなりませんが、ステートメントを使用追加することができます。

{% with total=0 %}
    {% for base_part in base_parts %}
        {% for k, v in base_part.items %}

        {# ...do stuff #}

        {# I try to get a running total of items to use as an ID #}
        totalId: {{ total|add:"1" }} <br/>
        {% endfor %}
    {% endfor %}
{% endwith %}

これはおそらくテンプレートレベルで機能しますが、より良いアプローチは、ビューレベルで計算し、計算された値を含む辞書をテンプレートに渡すことだと思います。

于 2012-12-14T01:01:26.637 に答える
0

ビューコードでそれを行うのは非常に効率的です...

    #Calculate the count
    count = 0
    for item in base_parts:
       count+=len(item.keys())

    run_range = range(count)

    return to the template

    #template
    {% for x in run_range|slice:'1' %}
    {{x}}
    {% endfor %}
于 2012-12-14T01:36:29.300 に答える
0

したがって、実際には辞書項目をリストに追加して、必要なものが最初になるようにしました。

base_parts = []
for k, v in rails_dic.items():
    base_parts.append({k: v})
for k, v in accessories_dic.items():
    base_parts.append({k: v})

これはこれを行うための最良の方法ではない可能性があり、正解としてよりpythonicな方法を受け入れています。

テンプレートでこれを処理することは、トリッキーで適切ではないと思います。これが、私がそれらの答えを受け入れない理由です。今後の訪問者には、テンプレートでハッキングする方法だけでなく、問題全体の解決策がより正しい方法で求められていることを確認してもらいたい.

于 2012-12-14T20:20:17.093 に答える