Jijna2 рекурсия всегда производит ошибку превышения глубины - PullRequest
2 голосов
/ 11 мая 2019

Раньше я никогда не использовал рекурсию дзиндзя, но, похоже, это должно быть относительно понятно.У меня проблемы с рендерингом данных в этом формате с помощью движка шаблонов.Следующий код на Python является хорошим примером того, что я пытаюсь воспроизвести в Jinja:

layers = {
    'groups': {
        'lower': {
            'groups': {},
            'layers': [{
                'layer_name': 'left #1',
            },
            {
                'layer_name': 'right #1',
            }]
        },
        'upper': {
            'groups': {},
            'layers': [{
                'layer_name': 'left',
            },
            {
                'layer_name': 'right',
            }]
        }
    },
    'layers': [{
        'layer_name': 'Background',
    }]
}

def printDict(_dict):
    for layer in _dict['layers']:
        print(layer['layer_name'])

    for group in _dict['groups']:
        print(group)
        printDict(_dict['groups'][group])

    printDict(layers)

Я пытаюсь сделать код шаблона максимально похожим на приведенную выше рабочую логику, например:

<ul>
    {% for node in layers recursive %}
        {% set outer_loop = loop %}
        {% if node == "layers" %}
            {% for layer in layers[node] %}
                <li>{{layer['layer_name']}}</li>
            {% endfor %}
        {% elif node == "groups" %}
            {% for group in layers[node] %}
                <li><b>{{group}}</b></li>
                <ul class="submenu">
                    {{ outer_loop(layers[node][group]) }}
                </ul>
            {% endfor %}
        {% endif %}
    {% endfor %}
</ul>

Однако каждый раз, когда я получаю «превышенную глубину рекурсии».Это очень неприятно для отладки, потому что нет никакого простого отладчика или метода для печати значений во время цикла.Кто-нибудь может заметить недостаток логики?

1 Ответ

1 голос
/ 12 мая 2019

Хорошо, я в конце концов выяснил метод работы.Проблема в том, что у Джинджи очень странная область видимости.В отличие от python, внутри циклов переменная не переназначается и продолжает использовать исходную глобальную переменную, что приводит к условию бесконечного цикла.Я решил эту проблему с помощью метода .items () при каждом рекурсивном вызове (и исходном вызове, чтобы сохранить согласованность), который создает новую переменную в локальной области видимости (я полагаю, возможно, она также просто перезаписывает переменную в глобальной области видимости)., но в любом случае это работает)

<ul>
    {% for key, v in layers,items() recursive %}
        {% set outer_loop = loop %}
        {% if key == "layers" %}
            {% for layer in v %}
                <li>{{layer['layer_name']}}</li>
            {% endfor %}
        {% elif key == "groups" %}
            {% for group in v %}
                <li><b>{{group}}</b></li>
                <ul class="submenu">
                    {{ outer_loop(v[group].items()) }}
                </ul>
            {% endfor %}
        {% endif %}
    {% endfor %}
</ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...