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)
Related
I have a flask server spitting out json data converted from pandas dataframe which look like:
[{'name': 'FBtr0075557',
'score': '164.00'},
{'name': 'FBtr0075557',
'score': '162.00'}]
The python code I'm using to convert the dataframe to json and serve in flask is:
result = df.to_json(orient="records")
parsed = json.loads(result)
return render_template('mirtar.html', targets=json.dumps(parsed))
When I use internal javascript, the data is parsed without any error:
<script type="text/javascript">
const targets = {{ targets|tojson }};
const entries = JSON.parse(targets);
console.log(entries);
</script>
However when I try to do the same using an external JS script, I get an error
Uncaught SyntaxError: Unexpected token { in JSON at position
From what I understand, the line const targets = {{ targets|tojson }}; in the external javascript doesn't behave the same way as in internal and the first '{' of the line is considered as an error.
I'm sure this is a very basic problem and there must be an easy way to do it that I have definitely missed.
Jinja syntax is only parsed in flask html templates, not externally loaded JS assets: because it's the python app doing the parsing, and in a deployed environment you'd typically serve static assets with a webserver like nginx.
The quickest way to sort this might be with this method where instead you use a data attribute within an HTML element. This appreciates that you're passing data to the template as an argument to render_template, so the data is present in the template at page load.
In your case this might look like
<!-- a hidden tag -->
<input type='hidden' id='targetid' data-thetargets='{{ targets|tojson }}' />
Then in your javascript load it up with:
var targets = JSON.parse(document.getElementById("targetid").dataset.thetargets);
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 attempting to get a JSON file into a script. I can't seem to be able to get it there by serving it from the filesystem so I made a view that returns the JSON data to the page like so:
def graph(request, d): #d.data is the file in the database
data = json.load(d.data)
return render(request, 'temp/template.html', {'json': data})
In my JS:
var j = {{ json|safe }};
When I look at the source for the JS it shows the data in this format:
{u'people': [{u'name': u'steve'}, {u'name': u'dave'}]}
Which I read shouldn't be a problem. I don't have any variables called 'id' and yet I get the error in the title pointing to the provided line of JS.
Why could this be? Also how do I then use the objects from the JSON in my script?
Solved by using simplejson:
import simplejson as json
And everything else as above. This is because the built in json.dumps returns an array of unicode like:
{u'people': [{u'name': u'steve'}, {u'name': u'dave'}]}
When using simplejson that shouldn't be a problem.
I have a custom template tag that returns suppose name of a student and roll number if passed as an argument id of the student.
#register.inclusion_tag('snippet/student_name.html')
def st_name_tag(profile, disp_roll=True, disp_name=True):
#some calculations
return {'full_name':student.name,
'roll':student.roll_number,
}
The template(included) consists of some Html file which is written in a single line(to avoid unterminated string literal error from js).
I simply want to call the st_name_tag from inside the JS function.
My JS looks like:
{% load profile_tag %}
<script type = "text/javascript">
eventclick : function(st){
var div = ('<div></div>');
var st_id = st.id;
if (st.status == 'pass'){
div.append('<p>Student Name:{% st_name_tag '+st_id+' %}</p>');
}
}
So far I tried the above method along with removing the + and '' signs from st_id varaible. That hasnt helped me at all. Help Please!
You are trying to render a template based on the interaction by user. The first happens on the server (server-side as it is often referred to), and the latter happens on the user's browser.
The order that these happen is first to render the template on server, send and present in browser, then user interacts with js. Because of this fact, as I mentioned in the comment, it is not possible to affect the template rendered within javascript.
I would recommend you to use ajax in order to accomplish this. Whenever an iteraction occurs, you asynchronously make a request to the server to present you with new data.
How do you safely render JSON data in a django webapp?
On the server in django I generate JSON data and then render that JSON data in a django template. The JSON occasionally contains snippets of html. Most of the time, that's fine, however if the </script> tag is inside the JSON data when it is rendered, it destroys the surrounding javascript.
For example...
On the server, in python I'll have this:
template_data = {
'my_json' : '[{"my_snippet": "<b>Happy HTML</b>"}]'
}
# pass the template data to the django template
return render_to_response('my_template.html', template_data, context_instance = c)
And then in the template:
<script type="text/javascript">
var the_json = {{my_json|safe}};
</script>
... some html ...
The resulting html works fine and looks like this:
<script type="text/javascript">
var the_json = [{"my_snippet": "<b>Happy HTML</b>"}];
</script>
... some html ...
However, you run into problems when, on the server, the JSON looks like this:
template_data = {
'my_json' : '[{"my_snippet": "Bad HTML</script>"}]'
}
return render_to_response('my_template.html', template_data, context_instance = c)
Now, when it's rendered, you'll get:
<script type="text/javascript">
var the_json = [{"my_snippet": "Bad HTML</script>"}];
</script>
... some html ...
The closing script tag within the JSON code is treated as closing the entire script block. All of your javascript will then break.
One possible solution is to check for </script> when passing the template data to the template, but I feel like there is a better way.
Safely insert the JSON as a string, and then call JSON.parse on it
Use escapejs instead of safe. It is designed for outputting to JavaScript.
var the_json = '{{my_json|escapejs}}';
To get a JavaScript object you then need to call JSON.parse on that string. This is always preferable than dumping a JSON-encoding into your script and evaluating it directly, for security reasons.
A useful filter to get python objects directly to the client that I use is this:
#register.filter
def to_js(value):
"""
To use a python variable in JS, we call json.dumps to serialize as JSON server-side and reconstruct using
JSON.parse. The serialized string must be escaped appropriately before dumping into the client-side code.
"""
# separators is passed to remove whitespace in output
return mark_safe('JSON.parse("%s")' % escapejs(json.dumps(value, separators=(',', ':'))))
And use it like:
var Settings = {{ js_settings|to_js }};