Uso de Flask Blueprint para estructurar aplicaciones. Parte 1ª.
En este capítulo veremos como optimizar la estructura de nuestras aplicaciones. Esto será especialmente útil cuando el proyecto alcanza un cierto tamaño y además es gestionado por diferentes personas. O también cuando queramos reutilizar parte del código en otros proyectos.
Para mejorar la estructura del programa vamos a utilizar planos o módulos (blueprint)
Hasta ahora todas las aplicaciones que hemos creado seguían la misma sencilla estructura, un archivo principal, unas pocas vistas, algunas plantillas etc.
Y todo su código, ya fuera más sencillo o más complejo seguía este mismo esquema. ¿Pero que pasa cuando la aplicación crece de tamaño? Pues si cojes, por ejemplo el código del capítulo 15, verás que el archivo inicio.py es mucho mas largo y complejo, que además hay varias plantillas dentro de templates y varios archivos.py junto al principal, conteniendo partes del proyecto. Vamos, que si no has seguido el proyecto desde el principio te parecerá un jaleo.
¿Y si esto lo juntamos con que el proyecto no sólo lo estas haciendo tú, sino que lo están elaborando varias personas? Pues que las probabilidades de que al ser el archivo principal tan grande, alguien de los que están trabajando en el modifique algo y estropee el trabajo del resto, son muy grandes.
Por ello lo ideal, es que te imagines el trabajo de cada uno de los participantes en el proyecto como unos módulos o compartimentos estancos en los que cada uno trabaja en su parte, sin afectar al resto y que al final se unen y esto es lo que hace que la aplicación este completa. Es como si la aplicación principal la dividiéramos en mini-aplicaciones. Eso es lo que van a hacer los Blueprints.
Para entender como se crean y como funcionan vamos a empezar con una aplicación muy sencilla en la que vamos a usar un único blueprint para ver como se crea y funciona, para luego coger el código del capitulo 15 y trasformarlo usando Blueprints.
Creamos una estructura básica típica de un directorio de Flask:
directorio_de_trabajo
|__ principal.py
|
|__ /templates
|__ /static
En principal.py escribimos el el código básico de una aplicación de Flask:
from flask import Flask
app=Flask(__name__)
@app.route('/')
def test():
return "<h1>Prueba</h1>"
if __name__=="__main__":
app.run(debug=True)
Bien, ahora crearemos una segunda vista (segunda.py), al mismo nivel que principal.py, que va a ser nuestro Blueprint de ejemplo. Si te fijas su construcción es muy parecida a como hemos creado la aplicación principal de Flask. Voy a escribir el código y comentamos el contenido.
segunda.py
Comenzamos importando el módulo Blueprint de Flask (al igual que en la aplicación principal hicimos con el modulo Flask)
Creamos una variable, que se suele llamar igual que el archivo o directorio que la contiene, en este caso, segunda. Esta variable será un objeto de Blueprint (al igual que en la aplicación principal "app" es un objeto de Flask -> app=Flask(__name__) )
El primer parámetro del Blueprint es su nombre. Se suele recomendar ponerle el mismo nombre que la variable y por tanto del archivo o directorio que lo contiene.
El segundo parámetro del Blueprint es la variable de importación que es una variable especial de python llamada __name__ (igual que en el proyecto principal)
El tercer parámetro static_folder y el cuarto template_folder son opcionales. Hacen referencia a si este Blueprint va a usar los directorios por defecto para plantillas y contenido estático de la aplicación principal (si los dejamos en blanco) o si por el contrario va a usar los suyos propios. Como ya dijimos el Blueprint es como una mini-aplicación y por tanto puede tener su propio lugar para guardar sus plantillas y su contenido estático independientemente de donde lo hagan las vistas del programa principal.
Por último usando el decorador, creamos dos vistas "home" e "/". Fíjate que aquí no usamos app.route sino que utilizamos el nombre del objeto de Blueprint, en este caso concreto "segunda.route".
Por último creamos la función que se aplicará a esas dos vistas, que será renderizar el archivo "home.html" que es una plantilla que nos da la bienvenida mostrando un pingüino de linux. (los archivos puedes encontrarlos en el código de la aplicación al final del capítulo)
Una vez que hemos creado el Blueprint hay que ir al programa principal y siempre es el mismo procedimiento. Importarlo y registrarlo en la aplicación principal.
Importarlo. Ten presente como es la estructura de la aplicación:
directorio_de_trabajo
|__ principal.py
|__ segunda.py
|__ templates
| |__ base.html
| |__ home.html
|__ static
Quedando el código de principal.py de la siguiente forma:
Pues ya tenemos creado el blueprint.
Date cuenta de que en nuestra segunda vista, hay dos rutas que llevan a que se renderice la plantilla "home.html". Una es ...route('/home/) y la otra es ...route('/'). Pero es que en la aplicación principal, también hay una vista ...route('/'), con el mismo nombre. ¿Que pasará cuando la invoquemos?
Vamos a comenzar con lo más obvio, invocando la vista home:
Hasta aquí todo normal. ¿Pero que pasa si llamamos a la vista ('/')? ¿Se rendizará la palabra "prueba" que es lo que dice la vista de principal.py o por el contrario saldrá de nuevo este bonito pingüino como esta codificado para la vista ('/') en segunda.py?
Si ejecutas el programa, nada más cargar el navegador en la vista principal obtendrás la respuesta:
Puedes encontar más información aquí.
Estructura de un proyecto con Blueprint
Ahora ha llegado el momento de ver realmente el potencial de los blueprint y como se puede utilizar para ordenar la aplicación y poder reutilizar el código.
Imaginemos, que no tenemos solo un segundo archivo con una sola vista sino que tenemos 100 archivos.py distintos cada uno con muchas vistas distintas. Además uno de ellos controla una parte de una aplicación de una empresa. Se puede corresponder con, por ejemplo, el segundo con la parte de administración, el tercero con la parte que gestiona el alta de clientes, el cuarto el que gestiona el control de las existencias de almacén, el quinto el que gestiona los productos que se venden online y así hasta que te alcance la imaginación.
Hagamos que cada uno de ellos se comporte como una aplicación propia, de manera que podamos trabajar con ella sin afectar al resto.
Comencemos creando algunas carpetas y trasladando archivos.
En el ejemplo anterior copia la siguiente estructura creando los directorios app y admin y moviendo los archivos que se indican. Crea los archivos __init__.py que son archivos vacíos que utilizamos en python para que se consideren los directorios como paquetes y podamos importar los objetos blueprint que necesitamos.
/app será el directorio padre que contendrá las diferentes partes de nuestra empresa (admin, ventas, gestión de inventarios, clientes etc). En este ejemplo práctico solo he puesto una, admin, pero podrían ser cientos, cada uno con sus propias rutas, plantillas y contenido estático independiente.
Como ves esta estructura de trabajo es más práctica e intuitiva para aplicaciones de gran tamaño.
directorio_de_trabajo
|__ principal.py
|__ /app
|__ __init__.py
|__ /admin
|__ __init__.py
|__ segunda.py
|__ /templates
|__ /static
En templates acuérdate de mover el archivo base.html y home.html que están dentro.
Si has hecho todo correctamente, para conseguir que funcione únicamente tendremos que cambiar la ruta desde la cual importamos el objeto blueprint, en este caso el código de primera.py que quedará así:
Ejecuta principal.py y comprueba que puedes acceder igualmente a cada una de las rutas que vimos antes de organizar y mover los archivos.
127.0.0.1:5000/
127.0.0.1:5000/admin/
127.0.0.1:5000/admin/home
Para que todo esto quede más claro, en el próximo capitulo vamos a ver como trasformar todo el código del capitulo 15, la aplicación "login de usuarios", utilizando blueprints.
Próximo Episodio: Flask 19. Usar Flask Blueprint para estructurar las aplicaciones. Parte 2ª