Search code examples
djangojinja2django-jsonfield

How to render an arbitrary set of key->value pairs from a JSONField in a Jinja2 template?


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


Solution

  • After a lot of hair-tearing, I discovered that Django templates are not quite exactly the same as Jinja2 templates.

    Specifically, what the J2 documentation told me to write as

    {% for key, value in log.log_data.items() %}
    

    should instead have been

    {% for key, value in log.log_data.items %}
    

    This worked and got me the output I was looking for. I'm leaving this as an answer here in case someone else runs into the same issue.