En esta lección, aprenderemos cómo manejar la carga de archivos en una aplicación Flask. La capacidad de cargar archivos es una funcionalidad común en muchas aplicaciones web, como cuando los usuarios suben imágenes de perfil, documentos, etc.

Objetivos de Aprendizaje

  • Configurar Flask para manejar cargas de archivos.
  • Crear formularios para la carga de archivos.
  • Procesar y guardar archivos en el servidor.
  • Validar tipos de archivos y tamaños.

Configuración Inicial

Antes de comenzar, asegúrate de tener Flask instalado. Si no lo tienes, puedes instalarlo usando pip:

pip install Flask

Configuración de la Aplicación

Primero, necesitamos configurar nuestra aplicación Flask para manejar cargas de archivos. Esto incluye definir una carpeta donde se guardarán los archivos subidos y establecer un tamaño máximo para los archivos.

from flask import Flask, request, redirect, url_for, render_template
import os

app = Flask(__name__)

# Configuración de la carpeta de carga
UPLOAD_FOLDER = 'uploads/'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# Configuración del tamaño máximo de archivo (en bytes)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16 MB

Creación del Formulario de Carga

Vamos a crear un formulario HTML simple para permitir a los usuarios cargar archivos. Utilizaremos Jinja2 para renderizar la plantilla.

<!-- templates/upload.html -->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cargar Archivo</title>
</head>
<body>
    <h1>Cargar Archivo</h1>
    <form method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="Subir">
    </form>
</body>
</html>

Manejo de la Carga de Archivos

Ahora, vamos a crear una ruta en nuestra aplicación Flask para manejar la carga de archivos. Esta ruta procesará el formulario y guardará el archivo en la carpeta especificada.

from werkzeug.utils import secure_filename

# Función para permitir solo ciertos tipos de archivos
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'png', 'jpg', 'jpeg', 'gif'}

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        # Verificar si el post request tiene la parte del archivo
        if 'file' not in request.files:
            return 'No file part'
        file = request.files['file']
        # Si el usuario no selecciona un archivo, el navegador también
        # enviará una parte vacía sin nombre de archivo
        if file.filename == '':
            return 'No selected file'
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return 'File successfully uploaded'
    return render_template('upload.html')

Explicación del Código

  1. Configuración de la Aplicación:

    • UPLOAD_FOLDER: Define la carpeta donde se guardarán los archivos subidos.
    • MAX_CONTENT_LENGTH: Establece el tamaño máximo permitido para los archivos subidos (16 MB en este caso).
  2. Formulario de Carga:

    • El formulario HTML utiliza el método POST y el tipo de codificación multipart/form-data para permitir la carga de archivos.
  3. Manejo de la Carga:

    • request.files['file']: Obtiene el archivo del formulario.
    • secure_filename(file.filename): Asegura que el nombre del archivo sea seguro para usar en el sistema de archivos.
    • file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)): Guarda el archivo en la carpeta especificada.

Ejercicio Práctico

Ejercicio 1: Validación de Tipos de Archivos

Modifica la función allowed_file para permitir solo archivos PDF y DOCX.

Solución:

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'pdf', 'docx'}

Ejercicio 2: Mostrar Archivos Subidos

Modifica la aplicación para mostrar una lista de archivos subidos en la página de carga.

Solución:

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            return 'No file part'
        file = request.files['file']
        if file.filename == '':
            return 'No selected file'
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('upload_file'))
    
    files = os.listdir(app.config['UPLOAD_FOLDER'])
    return render_template('upload.html', files=files)
<!-- templates/upload.html -->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cargar Archivo</title>
</head>
<body>
    <h1>Cargar Archivo</h1>
    <form method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="Subir">
    </form>
    <h2>Archivos Subidos</h2>
    <ul>
        {% for file in files %}
            <li>{{ file }}</li>
        {% endfor %}
    </ul>
</body>
</html>

Conclusión

En esta lección, hemos aprendido cómo manejar la carga de archivos en una aplicación Flask. Hemos cubierto la configuración de la aplicación, la creación de formularios de carga, el procesamiento y almacenamiento de archivos, y la validación de tipos de archivos. Con estos conocimientos, puedes implementar la funcionalidad de carga de archivos en tus propias aplicaciones Flask.

En la próxima lección, exploraremos cómo integrar bases de datos en nuestras aplicaciones Flask utilizando Flask-SQLAlchemy.

Curso de Desarrollo Web con Flask

Módulo 1: Introducción a Flask

Módulo 2: Conceptos Básicos de Flask

Módulo 3: Formularios y Entrada de Usuario

Módulo 4: Integración de Bases de Datos

Módulo 5: Autenticación de Usuarios

Módulo 6: Conceptos Avanzados de Flask

Módulo 7: APIs RESTful con Flask

Módulo 8: Despliegue y Producción

Módulo 9: Pruebas y Mejores Prácticas

Módulo 10: Extensiones y Ecosistema de Flask

© Copyright 2024. Todos los derechos reservados