Question
I'm making a website with Flask and I'd like to be able to execute python code
using data from the page. I know that I can simply use forms but it's a single
page that is continually updated as it receives user input and it'd be a
massive pain in the ass to have it reload the page every time something
happens. I know I can do {{ function() }}
inside the javascript but how do I
do {{ function(args) }}
inside the javascript using js variables? So far the
only thing I can think of is to update an external database like MongoDB with
the js then use Python to read from that, but this process will slow down the
website quite a lot.
The jQuery needs to get a list of dictionary objects from the Python function which can then be used in the html. So I need to be able to do something like:
JS:
var dictlist = { getDictList(args) };
dictlist.each(function() {
$("<.Class>").text($(this)['Value']).appendTo("#element");
});
Python:
def getDictList(args):
return dictlistMadeFromArgs
Answer
To get data from Javascript to Python with Flask, you either make an AJAX POST request or AJAX GET request with your data.
Flask has six HTTP methods
available, of
which we only need the GET and POST. Both will take jsdata
as a parameter,
but get it in different ways. That's how two completely different languages in
two different environments like Python and Javascript exchange data.
First, instantiate a GET route in Flask:
@app.route('/getmethod/<jsdata>')
def get_javascript_data(jsdata):
return jsdata
or a POST one:
@app.route('/postmethod', methods = ['POST'])
def get_post_javascript_data():
jsdata = request.form['javascript_data']
return jsdata
The first one is accessed by /getmethod/<javascript_data>
with an AJAX
GET as follows:
$.get( "/getmethod/<javascript_data>" );
The second one by using an AJAX POST request:
$.post( "/postmethod", {
javascript_data: data
});
Where javascript_data
is either a JSON dict or a simple value.
In case you choose JSON, make sure you convert it to a dict in Python:
json.loads(jsdata)[0]
Eg.
GET:
@app.route('/getmethod/<jsdata>')
def get_javascript_data(jsdata):
return json.loads(jsdata)[0]
POST:
@app.route('/postmethod', methods = ['POST'])
def get_post_javascript_data():
jsdata = request.form['javascript_data']
return json.loads(jsdata)[0]
If you need to do it the other way around, pushing Python data down to Javascript, create a simple GET route without parameters that returns a JSON encoded dict:
@app.route('/getpythondata')
def get_python_data():
return json.dumps(pythondata)
Retrieve it from JQuery and decode it:
$.get("/getpythondata", function(data) {
console.log($.parseJSON(data))
})
The [0]
in json.loads(jsdata)[0]
is there because when you decode a JSON
encoded dict in Python, you get a list with the single dict inside, stored at
index 0, so your JSON decoded data looks like this:
[{'foo':'bar','baz':'jazz'}] #[0: {'foo':'bar','baz':'jazz'}]
Since what we need is the just the dict inside and not the list, we get the item stored at index 0 which is the dict.
Also, import json
.