bozdoz
bozdoz

Reputation: 12860

Render template to escaped string for json in Django

This is more of a general python question, but it becomes a little more complicated in the context of Django.

I have a template, like this, simplified:

<span class="unit">miles</span>

I'm replacing an element with jquery and ajax:

$.getJSON('/getunit/', function(data){
   $('#unitHolder').html(data.unit_html);
});

Which goes to a view function to retrieve json data (more data than just this template). So I wanted to serve it up as json, and not just a string. So, the relevant code is this:

    ...
    context = { 'qs' : queryset }
    data['unit'] = render_to_string('map/unit.html', context)
    data = str(data).replace('\'','"') #json wants double quotes
return HttpResponse(data, mimetype="application/json")

This works for all of our other data, but not the template, because it has double quotes in it, that are not escaped. My question is, how do you escape a string in python to be used in a json format? Note that render_to_string() renders the string in unicode, thus u"<span>...</span>".

I've tried

import json
data['unit'] = json.dumps(render_to_string('map/unit.html', context))

But that gives me "unit": ""<span class=\\"unit\\">miles</span>"".

Also:

data['unit'] = str(render_to_string('map/unit.html', context)).replace('"','\"')

and:

data['unit'] = str(render_to_string('map/unit.html', context)).replace('"','\\"')

But neither escape the double quotes properly.

Upvotes: 2

Views: 3905

Answers (1)

bozdoz
bozdoz

Reputation: 12860

I hadn't tried json.dumps until I came into this problem. Previously I was just converting python dictionaries to strings and then replacing single quotes with double quotes. And for most of the data we've been passing to the client, it rendered correct JSON format. Now that I've tried json.dumps here in this problem, I realized that I don't need to convert dictionaries with str or replace anything. I can render the script as follows:

    ...
    context = { 'qs' : queryset }
    data['unit'] = render_to_string('map/unit.html', context)
    import json # I'll import this earlier
    data = json.dumps(data)
return HttpResponse(data, mimetype="application/json")

This works with all the data I'm passing to JSON format, so that works perfectly fine, and that's how I should have been doing it all along.

Upvotes: 3

Related Questions