Using JSON in django template
Asked Answered
S

4

21

I have a variable that contains JSON I need to pass into a template. I'm defining it as a variable and then passing it into the template successfully. However, I need the format to replace the quotes with ", but is replacing with '. This is causing issues with the service that I"m passing this to.

image_upload_params = 
{
  "auth": {
    "key": "xxx"
  },
  "template_id": "xxx",
  "redirect_url": "url-here",
}

Here is how it's coming up in the template:

{'redirect_url': 'url-here', 'template_id': 'xxx', 'auth': {'key': 'xxx'}}

Any idea how to get it to use " instead?

Stroll answered 8/6, 2011 at 22:46 Comment(0)
B
22

Use SafeString:

from django.utils.safestring import SafeString

def view(request):
    ...
    return render(request, 'template.html', {'upload_params': SafeString(json_string)})
Briarwood answered 8/6, 2011 at 22:54 Comment(2)
Thanks. I'm realizing the main issue. When I am setting the variable, python is changing my double quotes to single quotes. That's the root of the problem. For this service, I need for them to be double quotes. Ideas?Stroll
I'm perplexed why that would matter...if you use the json module it will safely escape everything for you. If you want to though, you can save the JSON as a string in the format you want, just mark it with SafeString and pass to the template.Briarwood
M
42

Django 2.1 added the json_script template filter:

Safely outputs a Python object as JSON, wrapped in a tag, ready for use with JavaScript

Insert this in your template:

{{ value|json_script:"hello-data" }}

It renders to:

<script id="hello-data" type="application/json">{"hello": "world"}</script>

Then, you can safely load this object in a JavaScript variable:

var value = JSON.parse(document.getElementById('hello-data').textContent);

This approach is safer than simply writing var value = {{value|safe}}; because it protects you from XSS attacks (more in this ticket).

Mallina answered 5/7, 2019 at 7:17 Comment(2)
a simpler way: {{ value|json_script:"hello_data" }} and access by var value = JSON.parse(hello_data.textContent);Chaffee
@anandogc, it works, but it is considered a bad practice. See https://mcmap.net/q/46611/-do-dom-tree-elements-with-ids-become-global-properties/1164966, for example.Mallina
B
22

Use SafeString:

from django.utils.safestring import SafeString

def view(request):
    ...
    return render(request, 'template.html', {'upload_params': SafeString(json_string)})
Briarwood answered 8/6, 2011 at 22:54 Comment(2)
Thanks. I'm realizing the main issue. When I am setting the variable, python is changing my double quotes to single quotes. That's the root of the problem. For this service, I need for them to be double quotes. Ideas?Stroll
I'm perplexed why that would matter...if you use the json module it will safely escape everything for you. If you want to though, you can save the JSON as a string in the format you want, just mark it with SafeString and pass to the template.Briarwood
U
1

I found a method which uses a django custom template filter.

The filter code looks like this

custom_filter.py

from django.template import Library
from django.utils.safestring import SafeString
import json

register = Library()


@register.filter("escapedict")
def escapedict(data):
    if not isinstance(data, dict):
        return data
    for key in data:
        if isinstance(data[key], int) and not isinstance(data[key], bool):
            data[key] = int(SafeString(data[key]))
        else:
            data[key] = SafeString(data[key])
    return json.dumps(data)

django document

And in the template, we use the filter like this:

...
{% load custom_filter %}
some html
...
onclick="jsfunc('{{data|escapedict}}')" 
...
some html
...
...
function showdetails(data){
    parse data here
}
...
...
Underpainting answered 26/7, 2017 at 12:28 Comment(0)
L
0

As zeekay mentioned, just use the python built-in json library. It will automatically output valid json data. You'll still have to mark it "safe" for django to use in templates but you can do that using the "safe" template filter.

Lobby answered 23/8, 2012 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.