I have a bunch of unicode strings in my data which I need to pass from my django view to template for using in a JavaScript scriptlet that passes it to the web back and forth.
The problem is I want the strings to be represented in the JavaScript unicode form but I get strings with a u prefix from python.
For example, for the string mężczyźni, Python stores it as u'm\u0119\u017cczy\u017ani' but when it is passed to the template, it does not remove the u prefix which creates problems for JavaScript while processing it. I want it to be simply 'm\u0119\u017cczy\u017ani' so that the JavaScript code in the template can use it.
I tried using urqluote, smart_unicode, force_unicode but couldn't hit a solution or even a hack.
What do I do ?
Edit: Django 1.7+ no longer includes simplejson. Instead of
from django.utils import simplejson
write
import json
and then use json instead of simplejson.
You are probably printing the python repr of your data dict, and trying to parse it in javascript:
{{ your_python_data }}
Instead, you could export your data in json:
from django.utils import simplejson
json_data_string = simplejson.dumps(your_data)
And load the data directly in javascript:
var your_data = {{ json_data_string }};
You could also make a template filter:
from django.utils import simplejson
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
#register.filter
def as_json(data):
return mark_safe(simplejson.dumps(data))
And in your template:
{% load your_template_tags %}
{{ your_python_data|as_json }}
Note that you should be careful with XSS, if some of "data" comes from user input, then you should sanitize it.
Related
In views.py, I have time series data stored in a dictionary as follows:
time_series = {"timestamp1": occurrences, "timestamp2": occurrences}
where each timestamp is in unix time and occurrences is an integer.
Is there a way to pass the time series data as a json object in the context of the render function?
Why do this: I am using Cal-heatmap on the front end which requires the data to be in json format. Ajax requests work just fine for now but I ideally would like to use the render approach if possible.
If a frontend library needs a to parse JSON, you can use the json library to convert a python dict to a JSON valid string. Use the escapejs filter
import json
def foo(request):
json_string = json.dumps(<time_series>)
render(request, "foo.html", {'time_series_json_string': json_string})
<script>
var jsonObject = JSON.parse('{{ time_series_json_string | escapejs }}');
</script>
Pass a json.dumps value to the template. It is already a valid JSON string so you don't need to parse it or anything. Only when rendering it in the template, mark it as safe to prevent HTML quoting.
# views.py
def foo(request):
time_series_json = json.dumps(time_series)
return render(request,
"template.html",
context={'time_series': time_series_json})
# in the template
<script>
const timeSeries = {{ time_series | safe }};
</script>
Using the Django templates built-in filter json_script:
In views.py:
render(request, "foo.html", {'time_series_data': time_series})
In the template foo.html:
{{ time_series_data|json_script:"time-series-data" }}
In your script:
const timeSeriesData = JSON.parse(document.getElementById('time-series-data').textContent);
have you tried passing something like json.dumps(time_series) to the render function?
I am building a Python/Flask based web app. The python script produces a dictionary of words and their corresponding weights. I have a javascript file (let's call it custom.js), which I call from the output.html. The way this javascript works is that it takes this dictionary and then uses d3.v3.min.js and d3.layout.cloud.js to create a wordcloud. When the dictionary is hard-coded into custom.js, the output file shows the wordcloud. However, the dictionary values will change depending on other parameters in the python script. Therefore, I would like to pass this dictionary from Python to custom.js. I am not sure how to do that.
I know that the parameters could be passed to HTML using {{ params |safe }}, but I am trying to figure out how to do that so that custom.js will receive the parameters (dictionary of words and weights, in this case) and word clouds can be rendered dynamically.
Thank you in advance!
If I understood you correctly you need to create a view function (a route) in the flask backend with url like this /get_dictionary. This function can look like this:
from flask import request, jsonify
...
#app.route('/get_dictionary'):
def get_dictionary():
...
your_dictionary = []
# Fill in your_dictionary with data
...
render_template('your_template.html', your_dictionary=your_dictionary)
EDIT:
You can pass the data from flask to script section of the html template using standard jinja2 notation:
<html>
<head>
<script>
your_dictionary = {{ your_dictionary | tojson }}
<!-- Do what you need with your_dictionary -->
</script>
...
</head>
...
you can try define a var in your template html, like this:
<script>
var your_var = '{{ value }}'
</script>
then use "your_var" in external js file. But please make sure above definition is at ahead of your js file refer.
I'm passing a dictionary from my Django view and want to access the dictionary in my code.
view code:
res.responses is a dictionary
def index(request):
import pprint
pprint.pprint(res.responses)
print 'type = ', type(res.responses)
return render_to_response("deploy/index.html", {"responses":res.responses})
Javascript code:
$(document).ready(function(){
//{% for each in responses%}
// console.log(Hi)
//{% endfor %}
var response = "{{responses}}"
console.log(response)
I tried accessing the variable directly using for loop and also accessing the variable directly. Both throw me an error. Please provide some suggestion.
You can do both.
Option 1:
Provide the script via a template that will send the code with the values. Will look ugly but work. Your javascript file or even the html must be parsed by the django template engine. They can't be static
Option 2:
Provide a new view with a json response, that is accessed from your javascript code (ie: via JQuery)
I am trying to send some schedule data to a webpage using Django and JSON format. My view to send this data looks like this:
def sessionscheduler(request):
c = connection.cursor()
c.execute("SELECT * FROM meter_schedule WHERE id = 1")
scheduleArray = []
for row in c.fetchall():
data = dict([('lastUpdate',row[1]), ('weekdaysOn',row[2]), ('weekdayChargeRateOffPeriodKwh',row[3]), ('weekdayEveningChargeOn',row[4]), ('weekdayEveningStart',row[5]),
('weekdayEveningDuration',row[6]), ('weekdayDayChargeOn',row[7]), ('weekdayDayStart',row[8]), ('weekdayDayDuration',row[9]), ('weekendsOn',row[10]),
('weekendChargeRateOffPeriodKWh',row[11]), ('weekendEveningChargeOn',row[12]), ('weekendEveningStart',row[13]), ('weekendEveningDuration',row[14]),
('weekendDayChargeOn',row[15]), ('weekendDayStart',row[16]), ('weekendDayDuration',row[17])])
scheduleArray.append(data)
jscheduleArray = json.dumps(scheduleArray)
context = {'jscheduleArray' : jscheduleArray}
return render(request, 'sessionscheduler.html', context)
I have used a template to render what is in jscheduleArray and it is coming out exactly how I want on the HTML page. However I want to use this data in my JavaSript file. The problem is that the quotes are not "" in the page source they are " which the script does not like. How do I fix this. Also I have a separte js file, is there anyway to directly call the JSON object into the the .js file? I am using YUI and pure JS.
I think you can use autoescape tag in your template to not escape the quotes
# sessionscheduler.html
{% autoescape off %}
{{ your_string }}
{% endautoescape %}
I have been able to pass primitive types such as integers like this, but I would like to pass more complicated objects, such as some the Django models that I have created. What is the correct way of doing this?
I know I'm a little late to the party but I've stumbled upon this question in my own work.
This is the code that worked for me.
This is in my views.py file.
from django.shortcuts import render
from django.http import HttpResponse
from .models import Model
#This is the django module which allows the Django object to become JSON
from django.core import serializers
# Create your views here.
def posts_home(request):
json_data = serializers.serialize("json",Model.objects.all())
context = {
"json" : json_data,
}
return render(request, "HTMLPage.html",context)
Then when I'm accessing the data in my html file it looks like this:
<script type = 'text/javascript'>
var data = {{json|safe}}
data[0]["fields"].ATTRIBUTE
</script>
data is a list of JSON objects so I'm accessing the first one so that's why it's data[0]. Each JSON object has three properties: “pk”, “model” and “fields”. The "fields" attribute are the fields from your database. This information is found here: https://docs.djangoproject.com/es/1.9/topics/serialization/#serialization-formats-json
For Django model instances in particular, you can serialize them into JSON and use the serialized value in your template context.
From there, you can simply do:
var myObject = eval('(' + '{{ serialized_model_instance }}' + ')');
or
var myObject = JSON.parse('{{ serialized_model_instance }}');
if using JSON-js (which is safer).
For Python objects in general see How to make a class JSON serializable