Как отобразить произвольный набор пар ключ->значение из JSONField в шаблоне Jinja2?
Я пытаюсь добавить отладочную информацию во фронтенд; по причинам, которые сейчас не нужно рассматривать, я храню соответствующую информацию в поле JSONField.
Хранение и извлечение информации работает правильно, но когда я пытаюсь вывести ее через J2 на страницу, на которой она должна быть, я сталкиваюсь с некоторыми проблемами.
Вот фрагмент, о котором идет речь:
{% for log in connection.debug_logs.all %}
<tr>
<td></td>
<td>{{ log.log_message }}</td>
<td>
{% for key in log.log_data %}
{{ key }}: {{ log.log_data.key }} <br/>
{% endfor %}
</td>
</tr>
{% endfor %}
Что я надеюсь на то, что это произведет серию строк key: value
. Что я получаю вместо этого, так это:
<td>Login requested by vmx1.internal (11.22.33.44)</td>
<td>
Framed-Route: <br/>
Service-Type: <br/>
Framed-IP-Address: <br/>
Framed-IPv6-Route: <br/>
control:Auth-Type: <br/>
Framed-IPv6-Prefix: <br/>
Delegated-IPv6-Prefix: <br/>
ERX-Egress-Policy-Name: <br/>
ERX-Ingress-Policy-Name: <br/>
ERX-Virtual-Router-Name: <br/>
control:Cleartext-Password: <br/>
</td>
Использование {{ log.log_data | pprint }}
дает ключи и значения, но отображает их в виде простой JSON-строки, которая сплющивается рендерером html и не очень полезна для отладки.
Попробовав вместо этого 'log.log_data[key]', вы получите ошибку 'Could not parse the remainder'.
Я попробовал предложения в этом вопросе, а также эти и несколько других, которые появились во время поиска в Google, но ни одно из них, похоже, не решает эту проблему - все они либо работают с известными ключами, либо работают с фактическим dict вместо JSONField, а иногда и с тем, и с другим.
Возможно, я упускаю что-то очень простое и понятное, но я исчерпал все способы сформулировать свой вопрос в поисковой системе. Есть советы?
Сделайте преобразование из json внутри вашего представления, чтобы иметь больший диапазон утилит, чем внутри мира шаблонов jinja2.
import json
DEBUG_LOGS_JSON = "[
{"log_data": {"Framed-Route": "route1", "Service-Type": "type1"}, "log_message": "my"},
{"log_data": {"Framed-Route": "route2", "Service-Type": "type2"}, "log_message": "name"},
{"log_data": {"Framed-Route": "route3", "Service-Type": "type3"}, "log_message": "Tarquinius"},
]"
def my_view(request):
my_dict = json.loads(DEBUG_LOGS_JSON) # instead you could also restructure the data passed to the template here.
return render("my_template.html", context=my_dict)
{% for dictionary in my_dict %}
<tr>
<td>{{ dictionary.log_message }}</td>
<td>
{% for key, value in dictionary.log_data.items() %}
{{ key }}: {{ value }} <br/>
{% endfor %}
</td>
</tr>
{% endfor %}
Если это не соответствует структуре вашего json, то, пожалуйста, приведите пример. Дайте мне знать, как это происходит.
После долгих терзаний я обнаружил, что шаблоны Django не совсем точно такие же, как шаблоны Jinja2.
Точнее, то, что в документации по J2 мне сказали написать как
{% for key, value in log.log_data.items() %}
вместо этого должно было быть
{% for key, value in log.log_data.items %}
Это сработало и дало искомый результат. Я оставляю это как ответ здесь на случай, если кто-то еще столкнется с той же проблемой.