helloflask / flask-dropzone Goto Github PK
View Code? Open in Web Editor NEWUpload files in Flask application with Dropzone.js.
Home Page: https://flask-dropzone.readthedocs.io
License: MIT License
Upload files in Flask application with Dropzone.js.
Home Page: https://flask-dropzone.readthedocs.io
License: MIT License
We are trying to implement chunking in our applications but it requires custom options for drop.zone.config.
Would you be interested in adding chunking? or point us in the right direction to improve the flask-dropzone to be more complex.
What is the limitation
I using string from documentation, and app fail on start
app.config['DROPZONE_ALLOWED_FILE_TYPE'] = 'image/*, .pdf, .txt'
and catch this error in logs
current_app.config['DROPZONE_ALLOWED_FILE_TYPE']]
KeyError: 'image/*, .pdf, .txt'
Hello. I'm unable to pass a variable to a template after a file upload. The code is modified basic example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask-Dropzone Demo: Basic</title>
{{ dropzone.load_css() }}
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
</head>
<body>
{{ dropzone.create(action='upload') }}
{{ dropzone.load_js() }}
{{ dropzone.config() }}
{% if message %}
<p>{{message}}</p>
{% endif %}
</body>
</html>
and the Python side
import os
from flask import Flask, render_template, request
from flask_dropzone import Dropzone
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config.update(
UPLOADED_PATH=os.path.join(basedir, 'uploads'),
# Flask-Dropzone config:
DROPZONE_ALLOWED_FILE_CUSTOM=True,
DROPZONE_ALLOWED_FILE_TYPE='.csv',
DROPZONE_MAX_FILE_SIZE=3,
DROPZONE_MAX_FILES=30,
DROPZONE_REDIRECT_VIEW='upload' # set redirect view
)
dropzone = Dropzone(app)
@app.route('/', methods=['POST', 'GET'])
def upload():
message = None
print(request.method, request.files)
if request.method == "POST":
# do something with the file ...
message = "done processing file"
return render_template('index.html', message=message)
if __name__ == '__main__':
app.run(debug=True)
But no 'message' is rendered. Basically the problem is that the only time the backend sees the uploaded file is when the request method is POST
, but then for some reason the message=message
argument does not work - nothing changes on the webpage.
The only way to pass a variable to a template is when the request method is GET
but then the backend does not see the uploaded file...
Any ideas how to solve this?
As far as I can tell, the DROPZONE_SERVE_LOCAL
option doesn't work when installing from pip. The entire static/ folder doesn't appear to be installed into a virtualenv I set up.
(venv) km@km-pt ~/p/sandbox> find . | grep dropzone -i
./venv/lib/python3.5/site-packages/flask_dropzone.py
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/WHEEL
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/INSTALLER
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/METADATA
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/top_level.txt
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/DESCRIPTION.rst
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/RECORD
./venv/lib/python3.5/site-packages/Flask_Dropzone-1.4.2.dist-info/metadata.json
./venv/lib/python3.5/site-packages/__pycache__/flask_dropzone.cpython-35.pyc
I looked inside the published .tar.gz file on pypi, which contained the static directory, but installing that with pip install Flask-Dropzone-1.4.2.tar.gz
made no difference.
Hi @greyli ,
Awesome plugin. I am using it to upload multiple files along with some server-side validation. Is there a way to return the individual status of each uploaded file? It is clear how to do it when only one file is being uploaded from https://github.com/greyli/flask-dropzone/blob/master/docs/advanced.rst#server-side-validation
Here's a barebones implementation of what works so far. I currently just append all error messages with the corresponding filename:
:
:
app.config['DROPZONE_UPLOAD_MULTIPLE'] = True
app.config['DROPZONE_MAX_FILE_SIZE'] = 10
app.config['DROPZONE_MAX_FILES'] = 5
app.config['DROPZONE_UPLOAD_ON_CLICK'] = True
:
:
@app.route('<upload_url>', methods=['GET', 'POST'])
def file_upload():
if request.method=='POST':
errors = []
for key, f in request.files.items():
if key.startswith('patent_file'):
filename = secure_filename(f.filename)
is_valid_file, msg, _, _ = validate_file(f, filename )
if not is_valid_file:
errors.append(filename + ' has error: ' + msg)
else:
f.save(os.path.join(app.config['UPLOADED_PATH'], patent_filename))
if len(errors)>0:
return ', '.join(errors), 400
return render_template('index.html')
This works. But it shows the same error message across all files. I am looking for a way to send individual status message per file. Is this achievable through the plugin? Thanks in advance.
Other details:
$ pip show flask_dropzone
Name: Flask-Dropzone
Version: 1.5.4
Summary: Upload file in Flask with Dropzone.js.
Home-page: https://github.com/greyli/flask-dropzone
Requires: Flask
Required-by:
Hi,
I would like to be able to fully use your extension, but I notice some limitations.
First, I can not choose the name of my dropzone, it is blocked at 'myDropzone'.
Secondly, which stems from the first rema, I can not have more than one dropzone per page which is a bit limiting.
Would it be possible to add the parameter id to dropzone.create () in order to fix a particular dropzone, knowing that if nothing is specified, 'myDropzone' will be used?
Regarding differentiate setting, I think this does not happen to be done. This can be done by limiting its python level setting to use the dropzone.config () view helper with the custom_init and custom_options parameters to do so.
Thank you for taking the time to read me, waiting for your answer.
Regards,
Celtic34fr
Béziers, Occitanie, France
Hello,
I tried to make single-page app with dropzone but my template is not rendered. Without dropzone, it works, so I believe I miss configurations. Here is simplified example:
app.py:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import pathlib
from flask import Flask, render_template, request
from flask_dropzone import Dropzone
app = Flask(__name__)
basedir = pathlib.Path(__file__).parent
app.config.update(
UPLOADED_PATH=pathlib.Path(basedir, "uploads"),
)
dropzone = Dropzone(app)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/", methods=["POST", "GET"])
def upload():
if request.method == "POST":
f = request.files.get("file")
if f.filename != "":
f.save(pathlib.Path(app.config["UPLOADED_PATH"], f.filename))
result = f"{f.filename} uploaded!"
print(result)
return render_template("result.html", message=result)
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask-Dropzone Demo</title>
{{ dropzone.load_css() }}
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
</head>
<body>
{{ dropzone.create('upload') }}
<!-- This works -->
<!--
<form method="POST" action="" enctype="multipart/form-data"><div>
<input type="file" name="file" id="inputFile01" style="max-width:700px;">
<button type="submit" value="Submit" id="submitfile">Submit</button>
</div></form>
-->
{% block content %}{% endblock %}
{{ dropzone.load_js() }}
{{ dropzone.config() }}
</body>
</html>
result.html:
{% extends "index.html" %}
{% block content %}
<h1>Result</h1>
<p>{{ message }}</p>
{% endblock %}
As there are more configuration than init and option, adding custom_func for config will make sense, and it is easy to realize.
I add the function for myself, hope to see more config option.
Flask已经没有Markup模块,需要从markupsafe中导入
when used mobility this system submits the form it is attached to after it finishes loading the previews for the files.
What's the best way to pass the uploaded filename(s) to the redirect url? e.g. something like:
{{ dropzone.config( redirect_url=url_for('view', file=filename) ) }}
Hello, not sure if this is the right place to ask but, is it possible to implement a dynamic confirm dialog on uploads? So that, for example, I could implement a serverside check which may fail an upload but then add a way to allow someone with admin privileges to "override" the serverside check and force an upload.
Change:
"Your can't upload any more files."
"You can't upload any more files."
Also, replace the token in dropzone.config(max_file_exceed='New label') doesn't work for this attribute. Only with app.config['DROPZONE_MAX_FILE_EXCEED'] = 'New label'
Edit: Turned out to be user error on my part! Sorry!
If you change the config call in examples/click-upload/templates/index.html to:
dropzone.config(custom_options='maxFiles: 3')
the rendered javascript uses the DROPZONE_MAX_FILES value defined in the app.config rather than 3. If you remove the MAX_FILES from config, the rendered javascript still ignores the 3 and uses null instead.
Additionally, how would one pass through something like DROPZONE_UPLOAD_ON_CLICK non-globally, ie: not in app.config?
I tried
{{ dropzone.create(action_view='upload_view') }}
just as how README described but an error happened then. When I change to
{{ dropzone.create(action_view='upload') }}
, all is fine.
Guess a typo there?
From flask-dropzone/examples/custom-option, whenever remove button is pressed, image (file) is removed from web-view but not from uploads folder.
How to check which image is removed by clicking on button & how to remove it from uploads?
And can I temp. save files for session & then based some logic decide to delete them or save permanently.
I'm trying to use Flask-Dropzone as part of a web-app to upload files for processing. These files typically don't have a file extension due to a quirk of the export process that generates these files.
I've consulted both the Flask-Dropzone docs and the Dropzone.js docs and both seem to imply that if DROPZONE_ALLOWED_FILE_CUSTOM = False
then every upload of all file types should be accepted. However, when navigating the file upload window, the filter defaults to "All Supported Types" and seems to only accept images. I can toggle this to "All Files" but when trying to upload anything else the dropzone gives the default error message about the file not being allowed.
I am able to set custom allowed file types such as .pdf's, .xlsx, etc. However this isn't useful as the files in question doesn't have a declared file type extension.
This can be recreated using the "multiple-dropzones" example and trying to upload any non-image file when the DROPZONE_ALLOWED_FILE_TYPE
config is deleted.
I do not know whether or not this a feature or a bug, but when I include the custom_options value in dropzone.config, like
{{ dropzone.config(custom_options='chunking: true,
forceChunking: true, chunkSize: 1000000,',
upload_action=url_for('upload.upload')) }}
Nothing works. No click to upload, no default text no nothing, even when I have this
dropzone.init_app(app)
app.config.update(
DROPZONE_ALLOWED_FILE_TYPE='default',
DROPZONE_IN_FORM=True,
DROPZONE_UPLOAD_ON_CLICK=True,
)
in the right place. I'm assuming that custom options overrides everything. How do I make it only affect the options that it is directly setting?
Just a small heads up in the sample code:
for key, f in request.files.iteritems()
for Python3 this should read:
for key, f in request.files.items()
I want to use some custom init in dropzone. I can only come up with only one bad way.
Since Jinja doesn't support statements (if, for) in {{ dropzone.config(custom_init = '') }}
because it's a variable, I have to put up some js code using python in Flask view functions.
Any better way?
Current implement is to add hidden csrf token input into the dropzone form, the ideal way should be to use the header.
<script type="text/javascript">
Dropzone.options.myDropzone.headers = {"X-CSRF-Token": "{{ csrf_token() }}"}
</script>
ImportError: cannot import name 'Markup' from 'flask'
HI there, i am making a blog app where user must submit at-least one image for post
kinda like required
attribute in input
tag (in html)
so i thought if there is DROPZONE_MAX_FILES
in config
Why not DROPZONE_MIN_FILES
What do you think about this?
1、上传完成后,如何返回文件路径给前端?尤其是多文件
2、上传文档类型是docx,doc,xls等office文件,是否可以显示文件类型图标?
The generated form should conditionally contain the following:
input(type='hidden', name='csrf_token', value='{{ csrf_token() }}')
I think, there is an logical error.
complete page should be called when after file totally uploaded. but example code not.
even file filtered by app.config still called completed page.
did I wrong??
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
The Traivs build is not triggered anymore.
I have set in my config file DROPZONE_MAX_FILES=3 and DROPZONE_PARALLEL_UPLOADS = 3 expecting all the files uploaded would be handles in one POST request, however each time i drop a file in the dropzone all files are being received but in different requests.
What i would like to achieve without having to save the files somewhere is to get a list of all files uploaded [file1, file2, file3] so i can later use them in a pandas method that can read and combine all files in one dataframe but at the moment the result i am getting with request.getlist() is a list containing one file per request like this: [file1] [file2] [file3].
Is there anyway to do this?
On a side note i am also a little bit confused about the DROPZONE_REDIRECT_VIEW option since is not working for me. Ex. {{ url_for('records.allrecords') }} is my view but DROPZONE_REDIRECT_VIEW = 'records.allrecors' doesn't work.
I would really appreciate an input on this. Thank you.
Hello,
Using the current setup of the docs, the csrf protection will apply to the every form and every post of the app, this config ideally should apply only to the upload of dropzone, not the entire app.
Suggestion: extend Dropzone embedded script via external file or config parameter.
I can take this task. It need for my own project.
Example: i need send api request before file physycally will be uploaded to server
DROPZONE_REDIRECT_VIEW (redirect_view) use url_for() to resolve the url, but i can not find any way to pass arguments. There is also no way of passing an url.
Suggestion1: use get_url() from utils.py so that its possible to pass complete url or for example '/index/2' this is OK as a quick fix. Must do it both at line 67 and 203
Suggestion2:
Fix/Clarify in the docs how to pass arguments with DROPZONE_REDIRECT_VIEW
手机上选择相册里的照片时不能选择多张,只能选择一张确定后再选择一张,怎么样才能像微信和QQ那样可以一起选择多张要上传的照片。
谢谢。
I have my flask application initializing the following (DROPZONE_IN_FORM=True
)
When I serve an HTML page with a dropzone within a <form>
this works, as expected.
When I serve a different HTML page that does not have a dropzone in <form>
i'm unable to override the config by passing the custom parameter to dropzone.config(in_form=False)
Would like to be able to override this parameter based on how the component is used on the HTML page.
Similar to this closed issue (just an extension to handle the updated DROPZONE_IN_FORM
config setting through the dropzone.config()
as part of the HTML page
#16
I'm using dropzone in a flask application that uploads files to AWS S3. I have the following configuration for the dropzone:
app.config.update(
DROPZONE_MAX_FILES=10,
DROPZONE_PARALLEL_UPLOADS=3,
DROPZONE_UPLOAD_MULTIPLE=True,
DROPZONE_ALLOWED_FILE_CUSTOM=True,
DROPZONE_MAX_FILE_SIZE=10000,
DROPZONE_ALLOWED_FILE_TYPE=".xls, .xlsx, .csv, .doc, .rtf",
DROPZONE_DEFAULT_MESSAGE="<br/><br/><br/>Drag files here or click to select",
DROPZONE_UPLOAD_ON_CLICK=True,
DROPZONE_UPLOAD_BTN_ID="upload_button",)
I notice that with this method, if a single file fails the upload (for ex, if the file is of the wrong type) none of the files are uploaded. The behavior that I would expect is that all of the other files continue to upload and only the single file that fails the file extension test does not upload. Below is the code for upload function in the flask application:
def upload():
if request.method == "POST":
for key, file in request.files.items():
if key.startswith('file'):
# Save file locally
if not os.path.exists(tmp_folder_path):
os.mkdir(tmp_folder_path, 0o777)
file.save(os.path.join(tmp_folder_path, file.filename))
return render_template("index.html")
I'm using Python 3.7.4 with the following packages:
boto3==1.16.11
botocore==1.19.11
click==7.1.2
Flask==1.1.2
Flask-Dropzone==1.5.4
itsdangerous==1.1.0
Jinja2==2.11.2
jmespath==0.10.0
MarkupSafe==1.1.1
python-dateutil==2.8.1
s3transfer==0.3.3
six==1.15.0
urllib3==1.25.11
Werkzeug==1.0.1
Dear greyli,
Thanks for your previous help in the previous issue #43
I meet another difficult problem, I found if I want to get the input "title" and "description" from html, I must set the "<form> </form>". And Your tutorial supplies a good way: https://github.com/greyli/flask-dropzone/blob/master/examples/in-form/app.py
I have a similar problem like the previous issue I asked. How do I send local variable "r" into the route "./form"? If the local variable "r" can be sent to "hand_form", I can get "title", "description" and return a new page. Please see the below code:
@app.route('/upload', methods=['POST'])
def handle_upload():
for key, f in request.files.items():
if key.startswith('file'):
f.save(os.path.join(app.config['UPLOADED_PATH'], f.filename))
r = dealFileFunction()
return '', 204
@app.route('/form/<r>', methods=['POST'])
def handle_form(r):
title = request.form.get('title')
description = request.form.get('description')
t = database().extract("r")
return render_template('another.html', title=title, description=description, r=r, t=t)
I have checked the HTML in https://github.com/greyli/flask-dropzone/blob/master/examples/in-form/templates/index.html
See below code:
<form action="{{ url_for('handle_form') }}" enctype="multipart/form-data" method="post">
<label for="title">Title</label>
<input type="text" id="title" name="title"/><br>
<label for="description">Description</label>
<input type="text" id="description" name="description"/><br>
{{ dropzone.create() }}
<input type="submit" id="submit" value="Submit and Upload">
</form>
{{ dropzone.load_js() }}
{{ dropzone.config() }}
It seems the action will return the "handle_form" directly when the uploaded job is complete. I also try the previous method:
{{ dropzone.config(custom_options="success: function(file, response){ window.location.href = '/handle_form/' + response.message; }") }}
And I also found "document.form.action=" can modify form action property. But both of two methods are failed. If it can be done like the previous way, the webserver can not only sends a local variable to return a new page, but also get "title" and "description" at same time.
Do you have a good idea to solve it?
Thanks for your warming answer.
Compare the following two writing styles of customizing the style for dropzone area:
<style>
.dropzone {
border: 2px dashed #0087F7;
margin: 10%;
min-height: 400px;
}
</style>
{{ dropzone.style('border: 2px dashed #0087F7; margin: 10%; min-height: 400px;') }}
The first one (standard style tag) has two pros:
.dropzone
to #<dropzone-id>
, while the second one cannot realize.Thus, I think the dropzone.style()
method is unnecessary, and I suggest writing the standard style tag for customizing the style.
What do you think?
@app.route('/completed')
def completed():
return '<h1>The Redirected Page</h1><p>Upload completed.</p>'
Now this code work, but there no way to show image count, render image previews etc. Would be perfect if post request will be redirected to this view.
@app.route('/completed'', methods=['POST', 'GET'])
def upload():
if request.method == 'POST':
.....
return '<h1>The Redirected Page</h1><p>Upload completed.</p>'
When uploading relatively large files (> 50 mb), the upload hangs indefinitely. The progress bar goes to 100% but never finishes. Any solutions for this? Is this a known issue?
I have a form for posting blog entries. I want to be able to submit multiple fields at once. Instead of designating the class of the form as 'dropzone' is it possible to be able to have a dropzone div nested in my current form so one button will submit all my fields, including multiple image upload, at once?
Something like this stackoverflow question, but with flask-dropzone. Thanx in advance for any assistance!
My form:
<!DOCTYPE HTML>
<form action="{{ url_for('add_post') }}" method="post" class="add-post" enctype="multipart/form-data">
<dl>
<dt>Post title:
<dd><input type="text" size="30" name="title" spellcheck="true" required>
<dt>Post date:
<dd><input type="date" name="post_date" required>
<dt>Post description(one sentence):
<dd><textarea name="description" rows="3" cols="40" spellcheck="true" required></textarea>
<dt>Post html file:
<dd><input type="file" name="html_file" required>
<dt>Post image(s) file:</dt>
<!--Can something like this be done?-->
<div class="dropzone" id="myDropzone">
{{ dropzone.create(action=url_for('show_posts')) }}
</div>
<dd><input type="submit" value="Submit">
</dl>
</form>
Is there feature implemented in backend?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.