Как отобразить произвольный набор пар ключ->значение из 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 %}

Это сработало и дало искомый результат. Я оставляю это как ответ здесь на случай, если кто-то еще столкнется с той же проблемой.

Вернуться на верх