22

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?

4 Answers 4

43

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

Sign up to request clarification or add additional context in comments.

2 Comments

a simpler way: {{ value|json_script:"hello_data" }} and access by var value = JSON.parse(hello_data.textContent);
@anandogc, it works, but it is considered a bad practice. See stackoverflow.com/q/3434278/1164966, for example.
22

Use SafeString:

from django.utils.safestring import SafeString

def view(request):
    ...
    return render(request, 'template.html', {'upload_params': SafeString(json_string)})

2 Comments

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?
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.
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
}
...
...

Comments

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.