Passing a variable from HTML to Flask through a button, changes the type to string

855 Views Asked by At

I need to pass a variable var from a HTML-page to flask, and have tried the code below, but the problem is that the request.form changes vars type from a dict to a string. I used json.loads(item) to change it back but the variables dict contains a datetime value which gives an error of json.decoder.JSONDecodeError: Expecting value: line 1 column 95 (char 94). I rather not have to deal with that it changes the type from the beginning, anyone with a better idea of passing variables from HTML to Flask?

In my_bookings.html :

<form action="#" method="POST">
   <input name="cancel_var" value="{{var}}" type=hidden>
   <button type="submit"> Cancel var </button>
</form>

In app.py:

@app.route('/my_bookings', methods=['GET', 'POST'])
def my_bookings():
if request.method == 'POST':
    var = request.form['cancel_var']
    cancel_var = json.loads(var) # This gives a json.decoder error because of one value is datetime-object

To clarify, the var is a dict and contains:

var = {"number": 3, "date": datetime.datetime(2020, 5, 14, 0, 0)} and comes back as a <class 'str'> to the Flask, but I want it to stay as a dict.

1

There are 1 best solutions below

3
Joran Beasley On

thats not really how it works .... but i guess you could do something crazy

import cPickle,base64

def my_endpoint():
    if request.method == "POST":
         my_data = request.form['cancel_var']
         my_data = base64.b64decode(my_data) # convert back to binary
         # note that pickle can be dangerous and this is really probably
         # not a good idea if someone might submit malicious code
         my_data = cPickle.loads(my_data) # back to python objects
         print("GOT DATA:",repr(my_data))    

    my_var = cPickle.dumps(var) # serialize to a string
    my_var = base64.b64encode(my_var) # ensure ascii character set
    return render('my_html.html',var=my_var)

but thats generally a pretty bad idea ... you could serialize to json instead of pickle (which is safer and faster) but json wont serialize your datetime thing

probably what you should do is not this....

instead you should just save the data to the users session and check it when they submit

def my_endpoint():
    if request.method == "POST":
         print("GOT DATA:",request.session['cancel_var'])    
    request.session['cancel_var'] = var
    return render('my_html.html',var="you dont need this")

or save it in the users cookies or a database or even in a file on disk... or maybe not at all as im not sure what you are trying to accomplish