helloflask/flask-dropzone

The problem of transfer the local variable when finish uploaded task

MolAICal opened this issue · 9 comments

I found a problem when I use the flask-dropzone. For example, please check the example: https://github.com/greyli/flask-dropzone/tree/master/examples/complete-redirect

For "app.py":

@app.route('/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
return render_template('index.html')

In the last line: return render_template('index.html'). If I want to transfer random local variable to another html as below:

@app.route('/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
r = math.random()
return render_template('another.html', r=r)

It seems the flask-dropzone cannot carry out the last sentence: return render_template('another.html', r=r). In this case, I cannot send the local variable "r" to another html page. If I set the "r" to global, the "r" will make a overrided mistake when many users request this function. It means the user may get another user's value. It is wrong.

It cannot solve this problem by the parameter DROPZONE_REDIRECT_VIEW='completed' or {{ dropzone.config(redirect_url=url_for('endpoint', id=id)) }} because it cannot get the local variable values in the one request of users.

Is any way to solve this problem? Or update flask-dropzone for it?

Thanks

Maybe you can save the variable in flask.session (Cookie):

from flask import session

@app.route('/', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        f = request.files.get('file')
        f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
        r = math.random()
        session['r'] = r
    return render_template('another.html')

Maybe you can save the variable in flask.session (Cookie):

from flask import session

@app.route('/', methods=['POST', 'GET'])
def upload():
    if request.method == 'POST':
        f = request.files.get('file')
        f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
        r = math.random()
        session['r'] = r
    return render_template('another.html')

Dear greyli,

We had tried session (Cookie) method. It is only suitable for many users to use different browsers and each user only submits one job. If one user submits many jobs in one browser, the session (Cookie) is equal to the global variable because the seesion[‘r’] is shared with these submitted jobs. The previous job will be overridden by the subsequent job.

In addition, we try many ways to solve this problem including threading, etc. It seems “return the local variables” is the best way. But flask-dropzone cannot carry out the last return sentence.

Do you have another good way to solve this problem?

Thanks.

How and where you use this variable? Could you provide a minimal and complete example for the idea you want to implement? Besides, this demo may help you.

How and where you use this variable? Could you provide a minimal and complete example for the idea you want to implement? Besides, this demo may help you.

Dear greyli,

I use your code to say our purpose, please check your complete-redirect example:
https://github.com/greyli/flask-dropzone/tree/master/examples/complete-redirect

@app.route('/', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
f = request.files.get('file')
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
r = math.random()
return render_template('index.html')

From your answer, I understand Dropzone.js will upload file in asynchronous AJAX request, it will not update the page with the response. So the “r” is no useful in the last sentence.

In the real production, when the users uploaded all files, we will set a function below “f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))” to deal with these uploaded data and feedback the results to the users. The results may be complex and not a string or number. I just use “r” as a simple example to replace the complex function.

Our purpose is how to transfer the results “r” value to another HTML page and show results to the users. If I use the DROPZONE_REDIRECT_VIEW='completed', how do we get “r” value from previous route “/”. See below code, we cannot get “r” value.

@app.route('/completed')
def completed():
return render_template('another.html', r=r)

How and where you use this variable? Could you provide a minimal and complete example for the idea you want to implement? Besides, this demo may help you.

I try to store all data into database, if I can transfer one value into completed route, I can extract them from database and return render_template('another.html', r=r, t=t):

@app.route('/completed/')
def completed(r):
t = database().extract("r")
return render_template('another.html', r=r, t=t)

I also try to use your supplied demo to redirect another route by use the respond message as below:
{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = "{{url_for('complete', r=response.message) }}"; }") }}

But the website cannot upload files. What is the problem?

I see. For the last method, try this:

{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = '%s'; }" % url_for('complete', r=response.message)) }}

I see. For the last method, try this:

{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = '%s'; }" % url_for('complete', r=response.message)) }}

Thanks for your answer. The webserver gives some errors, it seems variable "response" can not be recognized when it leave out of function(file, response){ window.location.href = '%s'; }.

The errors are shown as below:
jinja2.exceptions.UndefinedError: 'response' is undefined

Updated:

{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = '/completed/' + response.message; }") }}

{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = '/completed/' + response.message; }") }}

Many thanks. It is running now.