0

I'm trying to add debug information to a frontend; for reasons that don't need to be gone into at the moment I'm storing the pertinent information in a JSONField.

Storing and retrieving the information works correctly, but when I try to render it via J2 to the page it's supposed to be at I'm running into some issues.

Here's the segment in question:

          {% 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 %}

What I'm hoping for is for that to produce a series of lines of key: value. What I'm getting instead is:

                <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>

Using {{ log.log_data | pprint }} does yield the keys and values, but renders them as a plaintext JSON string which gets flattened by the html renderer and isn't terribly useful for debugging purposes.

Trying 'log.log_data[key]' instead yields a 'Could not parse the remainder' error.

I've tried the suggestions in this question as well as these and a few others that came up during google searches, but none of them seem to address this issue -- all of them are either working with known keys, working with an actual dict instead of a JSONField, or sometimes both.

I'm probably missing something very simple and straightforward, but I've run out of ways to phrase my question in a search engine. Any tips?

EDIT No, it is not actually a dictionary. I've also tried the solutions in this answer and that leads back to the Could not parse the remainder error.

So the data I'm looking for is absolutely there, I'm just having issues trying to get it to render properly.

Third and final edit: The problem was apparently that Django templates are not quite Jinja2 templates, and rather than {% for key, value in log.log_data.items() %} I needed to use {% for key, value in log.log_data.items %}

Shadur
  • 345
  • 3
  • 18
  • `{% for key, value in log.log_data.items() %}` and `{{ key }}: {{ value }}` if it is a dictionary: https://stackoverflow.com/questions/25373154/how-to-iterate-through-a-list-of-dictionaries-in-jinja-template – β.εηοιτ.βε Feb 07 '23 at 09:42
  • It's apparently *not* a dictionary. I've tried that one as well and that results in `Could not parse the remainder` errors. – Shadur Feb 07 '23 at 10:11
  • Turn the json to a dictionary inside your view and pass it to the template. Then change your template as β.εηοιτ.βε recommended above. – Tarquinius Feb 07 '23 at 11:41
  • @Tarquinius That sounds useful. Got an example? – Shadur Feb 07 '23 at 12:37
  • Does this answer your question? [How to iterate through a list of dictionaries in Jinja template?](https://stackoverflow.com/questions/25373154/how-to-iterate-through-a-list-of-dictionaries-in-jinja-template) – Sunderam Dubey Feb 07 '23 at 14:04
  • @sunderamdubey I'd already seen it, and no, it does not -- getting the Could Not Parse The Remainder error when I try to iterate over it the way β.εηοιτ.βε also suggested. – Shadur Feb 07 '23 at 14:52

1 Answers1

1

Do the conversion from json inside your view to have a greater range of utilities than inside the jinja2 template world.

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 %}

If this does not represent the structure of your json, then please provide an example. Let me know how it goes.

Tarquinius
  • 1,468
  • 1
  • 3
  • 18
  • Ahh, I see where I'm having the communication error. It's not a single view just for the debug info; the view is of the 'Connection' object that can have multiple `debug_log` objects attached, and each `debug_log` object has a `log_data` field that contains the JSON. But I'm gonna see if this gets me any further and let you know. – Shadur Feb 07 '23 at 13:08