Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The problem of transfer the local variable when finish uploaded task #43

Closed
MolAICal opened this issue Dec 7, 2020 · 9 comments
Closed
Labels

Comments

@MolAICal
Copy link

MolAICal commented Dec 7, 2020

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

@greyli
Copy link
Member

greyli commented Dec 8, 2020

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')

@greyli greyli added the question label Dec 8, 2020
@MolAICal
Copy link
Author

MolAICal commented Dec 8, 2020

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.

@greyli
Copy link
Member

greyli commented Dec 8, 2020

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.

@MolAICal
Copy link
Author

MolAICal commented Dec 8, 2020

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)

@MolAICal
Copy link
Author

MolAICal commented Dec 8, 2020

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?

@greyli
Copy link
Member

greyli commented Dec 8, 2020

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)) }}

@MolAICal
Copy link
Author

MolAICal commented Dec 8, 2020

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

@greyli
Copy link
Member

greyli commented Dec 8, 2020

Updated:

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

@MolAICal
Copy link
Author

MolAICal commented Dec 8, 2020

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

Many thanks. It is running now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants