HTMX 解析 JSON 响应问题
HTMX parsing JSON response issue
我有一个页面将一些数据发布到 Django 后端并返回 JSON 响应。我在使用模板解析它时遇到问题。
任何帮助,将不胜感激。提前谢谢你。
<div class="card-body">
<form>
{% csrf_token %}
<div class="input-group mb-3">
<label class="input-group-text">Command</label>
<select class="form-select" name="run_show_command" id="run_show_command">
<option selected disabled>Choose...</option>
<option value="{{ data.version.id }}:1">show ip interface brief</option>
<option value="{{ data.version.id }}:2">show interfaces description</option>
<option value="{{ data.version.id }}:3">show ip arp</option>
<option value="{{ data.version.id }}:4">show ip route</option>
<option value="{{ data.version.id }}:5">show ip cef</option>
<option value="{{ data.version.id }}:6">show version</option>
</select>
<button type="submit" class="btn btn-sm btn-success" hx-post="{% url 'inventory:device_run_command' %}" hx-target="#command_output" mustache-template="m_template" hx-indicator="#loader_bars">
<i class="fas fa-terminal"></i> Run
</button>
</div>
</form>
<div class="d-flex justify-content-center" hx-ext="client-side-templates" id="command_output">
<img id="loader_bars" class="htmx-indicator" alt="Loading..." src="{% static 'images/loaders/bars.svg' %}"/>
<template id="m_template" type="text/mustache">
{% for data in dataset %}
{% for key, value in data.items %}
<li>{{ key }} {{ value }}</li>
{% endfor %}
{% endfor %}
</template>
</div>
</div>
JSON:
[{ "intf": "GigabitEthernet1", "ipaddr": "10.10.20.48", "status": "up", "proto": "up" }, { "intf": "GigabitEthernet2", "ipaddr": "unassigned", "status": "administratively down", "proto": "down" }, { "intf": "GigabitEthernet3", "ipaddr": "unassigned", "status": "administratively down", "proto": "down" }, { "intf": "Loopback1", "ipaddr": "10.10.10.100", "status": "up", "proto": "up" }, { "intf": "Loopback123", "ipaddr": "unassigned", "status": "up", "proto": "up" }, { "intf": "Loopback510", "ipaddr": "50.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback511", "ipaddr": "51.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback512", "ipaddr": "52.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback666", "ipaddr": "6.6.6.6", "status": "up", "proto": "up" } ]
您不能像在 <template>
标记中那样在前端使用 Django 模板。 HTMX 支持 3 javascript 个模板库:mustache.js, handlebars and nunjucks。最接近Django的是nunjucks,它的灵感来自Jinja2,它的灵感来自Django Templates,所以会more-or-less熟悉
所以首先,不要忘记将 HTMX 扩展和 nunjucks 库添加到您的 JS 包中,或者直接添加到 HTML 基本模板中,例如:
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="https://unpkg.com/htmx.org@1.6.1/dist/ext/client-side-templates.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/3.0.1/nunjucks.min.js"
integrity="sha512-IIuR+Zp8wvP0dxNcSsRPoL7SXzP1kGmosDtcU7f6cPObZ9F5Ze/icFSRH/SqigP468jGwDm2XOE0/gSGm/cTBw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
更新后的模板:
<div class="card-body">
<form>
{% csrf_token %}
<div class="input-group mb-3" hx-ext="client-side-templates">
<label class="input-group-text">Command</label>
<select class="form-select" name="run_show_command" id="run_show_command">
<option selected disabled>Choose...</option>
<option value="{{ data.version.id }}:1">show ip interface brief</option>
<option value="{{ data.version.id }}:2">show interfaces description</option>
<option value="{{ data.version.id }}:3">show ip arp</option>
<option value="{{ data.version.id }}:4">show ip route</option>
<option value="{{ data.version.id }}:5">show ip cef</option>
<option value="{{ data.version.id }}:6">show version</option>
</select>
<button type="submit" class="btn btn-sm btn-success" hx-post="{% url 'inventory:device_run_command' %}"
hx-target="#command_output" nunjucks-template="m_template" hx-indicator="#loader_bars">
<i class="fas fa-terminal"></i> Run
</button>
</div>
</form>
<div class="d-flex justify-content-center">
<div id="command_output">
<img id="loader_bars" class="htmx-indicator" alt="Loading..." src="{% static 'images/loaders/bars.svg' %}" />
</div>
<template id="m_template">
{% verbatim %}
<ul>
{% for item in items %}
{% for key, value in item %}
<li>{{ key }} {{ value }}</li>
{% endfor %}
{% endfor %}
</ul>
{% endverbatim %}
</template>
</div>
</div>
请注意,我将 hx-ext
属性移到了按钮的父级 div 上,否则它将不起作用。 Nunjucks有相当similar syntax,但是比如我们不需要在嵌套循环中追加.items
编辑: 我之前错过了一个非常重要的细节:由于 nunjucks 和 DTL 的语法非常相似,我们必须将 nunjucks 模板嵌入到 {% verbatim %}
块中告诉 Django 忽略它。否则它会在后端由 Django 评估,而不是在前端由 nunjucks 评估。
此外,您的 JSON 文件中需要有一个顶级键,这将是第一个 for 循环中的键。
{
"items": [
{
"intf": "GigabitEthernet1",
"ipaddr": "10.10.20.48",
"status": "up",
"proto": "up"
},
{
"intf": "GigabitEthernet2",
"ipaddr": "unassigned",
"status": "administratively down",
"proto": "down"
},
]
}
我有一个页面将一些数据发布到 Django 后端并返回 JSON 响应。我在使用模板解析它时遇到问题。 任何帮助,将不胜感激。提前谢谢你。
<div class="card-body">
<form>
{% csrf_token %}
<div class="input-group mb-3">
<label class="input-group-text">Command</label>
<select class="form-select" name="run_show_command" id="run_show_command">
<option selected disabled>Choose...</option>
<option value="{{ data.version.id }}:1">show ip interface brief</option>
<option value="{{ data.version.id }}:2">show interfaces description</option>
<option value="{{ data.version.id }}:3">show ip arp</option>
<option value="{{ data.version.id }}:4">show ip route</option>
<option value="{{ data.version.id }}:5">show ip cef</option>
<option value="{{ data.version.id }}:6">show version</option>
</select>
<button type="submit" class="btn btn-sm btn-success" hx-post="{% url 'inventory:device_run_command' %}" hx-target="#command_output" mustache-template="m_template" hx-indicator="#loader_bars">
<i class="fas fa-terminal"></i> Run
</button>
</div>
</form>
<div class="d-flex justify-content-center" hx-ext="client-side-templates" id="command_output">
<img id="loader_bars" class="htmx-indicator" alt="Loading..." src="{% static 'images/loaders/bars.svg' %}"/>
<template id="m_template" type="text/mustache">
{% for data in dataset %}
{% for key, value in data.items %}
<li>{{ key }} {{ value }}</li>
{% endfor %}
{% endfor %}
</template>
</div>
</div>
JSON:
[{ "intf": "GigabitEthernet1", "ipaddr": "10.10.20.48", "status": "up", "proto": "up" }, { "intf": "GigabitEthernet2", "ipaddr": "unassigned", "status": "administratively down", "proto": "down" }, { "intf": "GigabitEthernet3", "ipaddr": "unassigned", "status": "administratively down", "proto": "down" }, { "intf": "Loopback1", "ipaddr": "10.10.10.100", "status": "up", "proto": "up" }, { "intf": "Loopback123", "ipaddr": "unassigned", "status": "up", "proto": "up" }, { "intf": "Loopback510", "ipaddr": "50.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback511", "ipaddr": "51.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback512", "ipaddr": "52.10.10.10", "status": "up", "proto": "up" }, { "intf": "Loopback666", "ipaddr": "6.6.6.6", "status": "up", "proto": "up" } ]
您不能像在 <template>
标记中那样在前端使用 Django 模板。 HTMX 支持 3 javascript 个模板库:mustache.js, handlebars and nunjucks。最接近Django的是nunjucks,它的灵感来自Jinja2,它的灵感来自Django Templates,所以会more-or-less熟悉
所以首先,不要忘记将 HTMX 扩展和 nunjucks 库添加到您的 JS 包中,或者直接添加到 HTML 基本模板中,例如:
<script src="https://unpkg.com/htmx.org@1.6.1"></script>
<script src="https://unpkg.com/htmx.org@1.6.1/dist/ext/client-side-templates.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/3.0.1/nunjucks.min.js"
integrity="sha512-IIuR+Zp8wvP0dxNcSsRPoL7SXzP1kGmosDtcU7f6cPObZ9F5Ze/icFSRH/SqigP468jGwDm2XOE0/gSGm/cTBw=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
更新后的模板:
<div class="card-body">
<form>
{% csrf_token %}
<div class="input-group mb-3" hx-ext="client-side-templates">
<label class="input-group-text">Command</label>
<select class="form-select" name="run_show_command" id="run_show_command">
<option selected disabled>Choose...</option>
<option value="{{ data.version.id }}:1">show ip interface brief</option>
<option value="{{ data.version.id }}:2">show interfaces description</option>
<option value="{{ data.version.id }}:3">show ip arp</option>
<option value="{{ data.version.id }}:4">show ip route</option>
<option value="{{ data.version.id }}:5">show ip cef</option>
<option value="{{ data.version.id }}:6">show version</option>
</select>
<button type="submit" class="btn btn-sm btn-success" hx-post="{% url 'inventory:device_run_command' %}"
hx-target="#command_output" nunjucks-template="m_template" hx-indicator="#loader_bars">
<i class="fas fa-terminal"></i> Run
</button>
</div>
</form>
<div class="d-flex justify-content-center">
<div id="command_output">
<img id="loader_bars" class="htmx-indicator" alt="Loading..." src="{% static 'images/loaders/bars.svg' %}" />
</div>
<template id="m_template">
{% verbatim %}
<ul>
{% for item in items %}
{% for key, value in item %}
<li>{{ key }} {{ value }}</li>
{% endfor %}
{% endfor %}
</ul>
{% endverbatim %}
</template>
</div>
</div>
请注意,我将 hx-ext
属性移到了按钮的父级 div 上,否则它将不起作用。 Nunjucks有相当similar syntax,但是比如我们不需要在嵌套循环中追加.items
编辑: 我之前错过了一个非常重要的细节:由于 nunjucks 和 DTL 的语法非常相似,我们必须将 nunjucks 模板嵌入到 {% verbatim %}
块中告诉 Django 忽略它。否则它会在后端由 Django 评估,而不是在前端由 nunjucks 评估。
此外,您的 JSON 文件中需要有一个顶级键,这将是第一个 for 循环中的键。
{
"items": [
{
"intf": "GigabitEthernet1",
"ipaddr": "10.10.20.48",
"status": "up",
"proto": "up"
},
{
"intf": "GigabitEthernet2",
"ipaddr": "unassigned",
"status": "administratively down",
"proto": "down"
},
]
}