Flask 继承并通过循环添加元素 jinja2.exceptions.UndefinedError: 'operation' is undefined

问题描述 投票:0回答:1

我完全对 jinja 标记感到困惑,我不明白,我做的一切是否完全错误,或者我的行为至少有一些逻辑? 我需要通过循环添加元素的帮助

Flask 错误 - jinja2.exceptions.UndefinedError:“操作”未定义

base.html:

<!-- Info about operations block-->
    <div class="about-operations-block">

           <!-- Button -->
            <div class="button-about-operations">
                <button class="btn-info" onclick="toggleInfo()">?</button>
                <script src="static/js/main.js"></script>
            </div>

            <!-- Info about operations -->
            <div class="info-about-operations">

                <!-- Title -->
                <div class="title-about-operations">
                    <h3 class="example-about-operations">{% block example_about_operation1 %} {% endblock %}</h3>
                    <h3 class="example-about-operations">{% block example_about_operation2 %} {% endblock %}</h3>
                </div>

                <!-- About Operations -->
                <div class="main-info-about-operations">
                    <h3 class="operation-name">{% block operation_name %} {% endblock %}</h3>
                    <p class="operation-info">{% block operation_info %} {% endblock %}</p>
                    <p class="res-example">{% block res_example %} {% endblock %}</p>
                </div>

            </div>

索引.html:

<!-- Info about operations block-->
    <!-- Title -->
    <div class="info-about-operations">
        {% block example_about_operation1 %} {{ data.example_about_operation1 }} {% endblock %}
        {% block example_about_operation2 %} {{ data.example_about_operation2 }} {% endblock %}
        
        <!-- Operations Info-->
        {% for operation in data['operations'] %}
            {% block operation_name %} {{ operation['operation_name'] }} {% endblock %}
            {% block operation_info %} {{ operation['operation_info'] }} {% endblock %}
            {% block res_example %} {{ operation['res_example'] }} {% endblock %}
        {% endfor %}
    </div>

数据.py:

data = {
    'example_about_operation1': 'A = { 1, 2, 3, 4 }',
    'example_about_operation2': 'B = { 3, 4, 5, 6 }',
    'operations': [
        {
            'operation_name': 'Merge',
            'operation_info': 'Write the elements of the set A and B in ascending order; if an element occurs >1 '
                              'time, write it once',
            'res_example': 'A ⋃ B = { 1, 2, 3, 4, 5, 6 }'
        },
        {
            'operation_name': 'Intersection',
            'operation_info': 'Write out identical elements from A and B',
            'res_example': 'A ⋂ B = { 3, 4 }'
        },
        {
            'operation_name': 'Difference',
            'operation_info': 'Rewrite A, removing elements that are in B',
            'res_example': 'A \ B = { 1, 2 }'
        },
        {
            'operation_name': 'Symmetrical Difference',
            'operation_info': 'Write out elements from A ⋃ B, removing elements from A ⋂ B',
            'res_example': 'A △ B = { 1, 2, 5, 6}'
        },
    ]
}

# It's for testing, because I'm already thinking I'm full idiot, and I'm not sure, but it's kinda "working"...
for operation in data['operations']:
    print(operation['operation_name'])
    print(operation['operation_info'])
    print(operation['res_example'])

应该发生什么:使用循环从 data 字典中添加元素in:

base.html:

<!-- Info about operations -->
            <div class="info-about-operations">

                <!-- Title -->
                <div class="title-about-operations">
                    <h3 class="example-about-operations">{% block example_about_operation1 %} {% endblock %}</h3>
                    <h3 class="example-about-operations">{% block example_about_operation2 %} {% endblock %}</h3>
                </div>

                <!-- About Operations -->
                <div class="main-info-about-operations">
                    <h3 class="operation-name">{% block operation_name %} {% endblock %}</h3>
                    <p class="operation-info">{% block operation_info %} {% endblock %}</p>
                    <p class="res-example">{% block res_example %} {% endblock %}</p>
                </div>

            </div>

index.html:

<!-- Info about operations block-->
    <!-- Title -->
    <div class="info-about-operations">
        {% block example_about_operation1 %} {{ data.example_about_operation1 }} {% endblock %}
        {% block example_about_operation2 %} {{ data.example_about_operation2 }} {% endblock %}

        <!-- Operations Info-->
        {% for operation in data['operations'] %}
            {% block operation_name %} {{ operation['operation_name'] }} {% endblock %}
            {% block operation_info %} {{ operation['operation_info'] }} {% endblock %}
            {% block res_example %} {{ operation['res_example'] }} {% endblock %}
        {% endfor %}
    </div>

但我有一个错误 - jinja2.exceptions.UndefinedError:“操作”未定义。

如果我尝试在没有 jinja 的情况下做这样的事情,它会有点工作(我知道这有点不同,但仍然。我想我的大脑很快就会爆炸,因为我不明白为什么它不起作用):

数据.py:

data = {
    'example_about_operation1': 'A = { 1, 2, 3, 4 }',
    'example_about_operation2': 'B = { 3, 4, 5, 6 }',
    'operations': [
        {
            'operation_name': 'Merge',
            'operation_info': 'Write the elements of the set A and B in ascending order; if an element occurs >1 '
                              'time, write it once',
            'res_example': 'A ⋃ B = { 1, 2, 3, 4, 5, 6 }'
        },
        {
            'operation_name': 'Intersection',
            'operation_info': 'Write out identical elements from A and B',
            'res_example': 'A ⋂ B = { 3, 4 }'
        },
        {
            'operation_name': 'Difference',
            'operation_info': 'Rewrite A, removing elements that are in B',
            'res_example': 'A \ B = { 1, 2 }'
        },
        {
            'operation_name': 'Symmetrical Difference',
            'operation_info': 'Write out elements from A ⋃ B, removing elements from A ⋂ B',
            'res_example': 'A △ B = { 1, 2, 5, 6}'
        },
    ]
}

# It's for testing, because I'm already thinking I'm full idiot, and I'm not sure, but it's kinda "working"...
for operation in data['operations']:
    print(operation['operation_name'])
    print(operation['operation_info'])
    print(operation['res_example'])

如果我尝试输出这个:

base.html:

 <div class="title-about-operations">
                    <h3 class="example-about-operations">{% block example_about_operation1 %} {% endblock %}</h3>
                    <h3 class="example-about-operations">{% block example_about_operation2 %} {% endblock %}</h3>
</div>

index.html:

 {% block example_about_operation1 %} {{ data.example_about_operation1 }} {% endblock %}
 {% block example_about_operation2 %} {{ data.example_about_operation2 }} {% endblock %}

就可以正常输出了。

请告诉我为什么这不起作用,谢谢。

python flask jinja2
1个回答
0
投票

您使用块的方式与其预期目的不符。

模板继承

块是父模板中的定义,可在子模板中使用。
模板不知道循环的嵌套上下文,因此也不知道变量。这会导致收到错误消息。

base.html
<!DOCTYPE html>
<html>
<head>
    {% block head %}
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{% block title %}{% endblock %}</title>
    {% endblock %}
</head>
<body>
    <main>
        {% block content %}{% endblock %}
    </main>
    {% block scripts %}{% endblock %}
</body>
</html>

宏非常适合与循环结合使用。它对应于可以处理一个或多个项目的渲染的预定义函数。可以在模板外部定义宏,然后导入。这使得可以在多个模板中使用它。

index.html(宏)
{% extends 'base.html' %}

{# This code can also be stored in another file and imported. #}
{% macro op(operation_name, operation_info, res_example) -%}
    <h3 class="operation-name">{{ operation_name }}</h3>
    <p class="operation-info">{{ operation_info }}</p>
    <p class="res-example">{{ res_example }}</p>
{%- endmacro %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
{% endblock %}

{% block content %}
    <div class="about-operations-block">
        <div class="button-about-operations">
            <button class="btn-info" onclick="toggleInfo()">?</button>
        </div>

        <!-- Info about operations -->
        <div class="info-about-operations">

                <!-- Title -->
                <div class="title-about-operations">
                        <h3 class="example-about-operations">{{ data.example_about_operation1 }}</h3>
                        <h3 class="example-about-operations">{{ data.example_about_operation2 }}</h3>
                </div>

                <!-- About Operations -->
                <div class="main-info-about-operations">
                    {% for operation in data.operations %}
                        {{ op(**operation) }}
                    {% endfor %}
                </div>

        </div>
    </div>
{% endblock %}

{% block scripts %}
    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
{% endblock %}
包括

也可以使用包含。一个文件内是外包代码,可以多次嵌入。

index.html(包含)
{% extends 'base.html' %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
{% endblock %}

{% block content %}
    <div class="about-operations-block">
        <div class="button-about-operations">
            <button class="btn-info" onclick="toggleInfo()">?</button>
        </div>

        <!-- Info about operations -->
        <div class="info-about-operations">

                <!-- Title -->
                <div class="title-about-operations">
                        <h3 class="example-about-operations">{{ data.example_about_operation1 }}</h3>
                        <h3 class="example-about-operations">{{ data.example_about_operation2 }}</h3>
                </div>

                <!-- About Operations -->
                <div class="main-info-about-operations">
                    {% for operation in data.operations %}
                        {% include 'operation.html' %}
                    {% endfor %}
                </div>

        </div>
    </div>
{% endblock %}

{% block scripts %}
    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
{% endblock %}
操作.html
<h3 class="operation-name">{{ operation.operation_name }}</h3>
<p class="operation-info">{{ operation.operation_info }}</p>
<p class="res-example">{{ operation.res_example }}</p>
© www.soinside.com 2019 - 2024. All rights reserved.