Subida de ficheros
Es posible realizar subidas de ficheros al servidor, Flask nos ofrece está posibilidad, pero vamos a utilizar la extensión Flask-WTF para facilitar esta labor. Hay que recordad que cuando se manda un fichero al servidor la información del fichero la encontramos en request.file
.
En esta unidad vamos a hacer una aplicación web que nos permita generar una galería de imágenes. En nuestra galería vamos a poder subir imágenes a través de un formulario.
Creando un formulario para subir ficheros
Vamos a utilizar el tipo de campo FileField
para crear nuestro formulario para subir un fichero.
from flask_wtf import FlaskForm
from wtforms import SubmitField
from flask_wtf.file import FileField, FileRequired
class UploadForm(FlaskForm):
photo = FileField('selecciona imagen:',validators=[FileRequired()])
submit = SubmitField('Submit')
Además hemos introducido una validación, indicando que es necesario indicar un fichero.
Generando el formulario
De forma similar a lo que vimos en la unidad anterior vamos a generar el formulario en nuestra plantilla:
<form action="{{url_for('upload')}}" method="POST" enctype="multipart/form-data">
{{ form.csrf_token }}
{{form.photo.label() }}{{form.photo()}}<br/>
<br/>
{{form.submit()}}
</form>
Al subir un fichero es necesario poner el atributo enctype="multipart/form-data"
al definir el formulario.
Tratamiento del fichero subido
Al crear la vista vamos a crear un formulario:
form = UploadForm()
Al construir el objeto formulario no hemos indicado con que valores vamos a rellenar el formulario (en la unidad anterior lo indicábamos de esta manera: form = UploadForm(request.form)
). Cuando creamos un objeto de esta manera, automáticamente carga el formulario con los datos (request.form
) y con los posibles ficheros que hayamos subido (request.file
), por lo que tenemos a nuestra disposición los datos y los ficheros recibidos.
Si el formulario es válido:
-
Creamos un objeto fichero a parir del formulario
f = form.photo.data
-
Creamos un nombre de fichero que sea compatible con el sistema de archivo (lo hacemos con la función
secure_filename
)filename = secure_filename(f.filename)
-
Y lo guardamos en el directorio adecuado.
f.save(app.root_path+"/static/img/"+filename)
-
Finalmente realizamos una redirección al inicio de la página.
return redirect(url_for('inicio'))
La vista completa quedaría de la siguiente manera:
@app.route('/upload', methods=['get', 'post'])
def upload():
form= UploadForm() # carga request.from y request.file
if form.validate_on_submit():
f = form.photo.data
filename = secure_filename(f.filename)
f.save(app.root_path+"/static/img/"+filename)
return redirect(url_for('inicio'))
return render_template('upload.html', form=form)