使用 Jinja2 将 JSON 从 Python 脚本传递并解析到 HTML 模板

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

我有一个生成 HTML 文件的 python 函数。它在 Jinja2 的帮助下根据收到的参数填充一些字段和一个具有动态值的表。该表具有旧值和新值,它们是名为 diff_values 的 json 变量的一部分。现在,该表对于每个更改(差异)值都有一个复选框,选择必要的复选框后,它应该用已检查的键值对的更新值替换原始 JSON。这是我执行此操作的代码:

助手.py

import json
from jinja2 import Environment, FileSystemLoader

def create_html_content(diff_data):
    # Load the Jinja2 template
    env = Environment(loader=FileSystemLoader('.'))
    template = env.get_template('template.html')

    # Prepare the data for rendering
    data = {
        'suite_name': diff_data['suite_name'],
        'test_case_name': diff_data['test_case_name'],
        'expected_json_path': diff_data['expected_json_path'],
        'diff': diff_data['diff']['values_changed'],
        'diff_values': json.dumps(diff_data['diff']).replace('</', '<\\/')  # Avoid script injection
    }

    # Render the template with the data
    html_content = template.render(data)
    return html_content

模板.html

<html>
<head>
    <title>Differences</title>
</head>
<body>
    <h1>Difference Details</h1>
    <p>Suite: {{ suite_name }}</p>
    <p>Test Case: {{ test_case_name }}</p>
    <p>Expected JSON Path: {{ expected_json_path }}</p>
    <table border="1">
        <tr>
            <th>Select</th>
            <th>Attribute</th>
            <th>Old Value</th>
            <th>New Value</th>
        </tr>
        {% for key, value in diff.items() %}
        <tr>
            <td><input type="checkbox" data-attribute="{{ key }}"></td>
            <td>{{ key.split("root['")[1].split("']")[0] }}</td>
            <td>{{ value.old_value }}</td>
            <td>{{ value.new_value }}</td>
        </tr>
        {% endfor %}
    </table>
    <button onclick="submitSelected()">Accept Selected Changes</button>
    <script>
    function submitSelected() {
        var selectedDiffs = JSON.parse(JSON.stringify(diffValues)); // Deep copy of diffValues
        selectedDiffs.values_changed = {}; // Reset the values_changed object
        console.log("BEFORE FOR LOOP: ", selectedDiffs)
        document.querySelectorAll('input[type="checkbox"]:checked').forEach(function(checkbox) {
            var attribute = checkbox.getAttribute('data-attribute');
            console.log("INSIDE FOR LOOP, ATTRIBUTE:", attribute)
            console.log("INSIDE FOR LOOP, DIFF VAL: ", diffValues.values_changed[attribute])
            selectedDiffs.values_changed[attribute] = diffValues.values_changed[attribute];
        });
        console.log("AFTER: ", selectedDiffs);

        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://localhost:8000/submit", true);
        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        xhr.send(JSON.stringify(selectedDiffs));
        xhr.onload = function() {
            if (xhr.status == 200) {
                alert('Selected changes submitted');
            } else {
                alert('Failed to submit selected changes');
            }
        };
    }
    var diffValues = {{ diff_values | tojson }};
    </script>
</body>
</html>

我在

var diffValues = {{ diff_values | tojson }};
中遇到了 linting 问题,但不知道如何解决它。

现在我的主要问题是当我选择复选框并单击“接受选定的更改”时,我收到错误:

未捕获类型错误:无法读取未定义的属性(读取 'root['key1']')

代码中的日志是: FOR 循环之前: {"values_changed": {"root['key1']": {"new_value": "value1", "old_value": "value9"}, "root['key3']": {"new_value" :“值3”,“旧值”:“值8”}}}

FOR 循环内部,属性:root['key1']

之后它给出错误,因此不再有控制台日志。它基本上无法通过执行

diffValues.values_changed[attribute]
来访问“root['key1']”的键值对,但是为什么当键退出时它会失败?

javascript python html jinja2
1个回答
0
投票

你的

diffValues
是一个字符串,而不是一个对象。因为在将其传递给模板之前,您在 Python 中
json.dumps
它(此时它是一个字符串),然后在模板中再次
tojson
它,这保留了它的字符串性。因此
.values_changed
不存在于所述字符串上,而是
undefined
,并且尝试访问
[attribute]
上的
undefined
会导致错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.