Usar Flask Blueprint para estructurar aplicaciones. Parte 2ª.
Usar Flask Blueprint para estructurar aplicaciones. Parte 2ª.
División Estructural.
División Funcional.
Bloque de páginas públicas (En nuestro caso solamente la pagina_inicial)
"Primero creación e inicialización del blueprint y segundo registro del mismo en la aplicación principal, en nuestro caso inicio.py".
En este último __init__.py que hemos creado, el que esta dentro del directorio public, tecleamos:
Esto ya lo habíamos visto lo que significaba en el capítulo anterior. Lo único nuevo es el "from . import routes". Con esto, lo que le decimos al programa es que de este mismo directorio, en donde esta el __init__.py, importe el módulo routes, que vamos a crear a continuación. Pero antes de esto creamos dentro del directorio public, la carpeta templates y cortamos y pegamos la plantilla pagina_inicial.html, que está en el directorio templates, pero en el primer nivel del directorio de trabajo.
Ahora si, creamos el archivo routes.py que contendrá la ruta de la vista de esta página_inicial.
routes.py
Comentémoslo un poco.
En la primera línea importamos el método render_template para poder renderizar la plantilla página_inicil.html. Luego le decimos que importe el objeto blueprint public que está en el mismo directorio y que creamos en el archivo __init__.py. Para finalizar con una función que define la vista de la manera habitual.
Sin embargo esto aún no funcionaría porque nos falta un último paso, que es registrar el blueprint en la aplicación principal. Para ello en el archivo inicio.py antes de declarar las vistas tecleamos:
Le estamos diciendo que importe el blueprint public y lo registre en la aplicación principal de Flask que es "app".
Ahora cada vez que vayamos a la url 127.0.0.1:5000 se utilizará este blueprint para ir a la página principal.
IMPORTANTE:
Date cuenta que esta vista ya estaba definida en el archivo inicio.py con lo que tienes que buscar y borrar su código en este archivo, en inicio.py. Si no lo haces tendrías una función "/" en inicio.py y otra función "/" en /app/public/routes.py
Para que quede un poco más claro la estructura de la aplicación hasta el momento quedará de la siguiente forma:
Si ahora pruebas el programa se renderizará la página principal correctamente, pero si intentas ir a otras opciones nos dará un error, puesto que ahora todo lo que hace referencia a el archivo pagina_inicial.html no está en el directorio templates principal, sino que se encuentra ahora en app/public/templates, ha cambiado la dirección a la que apuntan. Esto lo vamos a ir arreglando sobre la marcha según vayamos cambiando el resto de las plantillas.
Bloque de páginas privadas (a las que se puede acceder una vez logeados)
Bloque relacionado con las funciones de autentificación de usuarios.
1. from . import auth
from . import auth
# cortado y pagado de la vista login desde inicio
@auth.route('/login/', methods=['GET', 'POST'])
def login():
form = Formulario_de_Login()
# (2) Si el usuario ya estuviera registrado no tiene sentido que volviera a hacer un login
# asi que lo mandamos de vuelta a la página del dashboard
por lo anterior
...
HASTA
...
# Si el usuario no existe o la contraseña es incorrecta
# return "<h2>Usuario o Contraseña incorrecta</h2>"
flash('El usuario no existe o la contraseña es incorrecta')
return redirect(url_for('login'))
else:
return render_template('login.html', form=form)
Esto se debe a que al intentar renderizar la página principal, los url_for que hacen referencia a esta vista se están buscando en la aplicación principal "app". Sin embargo no debe buscarlos ahí pues hemos movido la definición de esta vista al blueprint "auth". Afortunadamente el mismo programa nos da la solución, que es tan sencilla como en la plantilla que se carga al inicio, pagina_inicial.html, indicar en todos url_for los blueprint a los que corresponden. En esta primera vista es sustituir "login" por "auth.login"
1 from . import auth
2 from .form import Formulario_de_Login
from . import auth
from .form import Formulario_de_Login, Formulario_de_Registro
from flask import redirect, url_for, request, render_template, flash
# Por temas de seguridad en la ruta
from werkzeug.urls import url_parse
# para que la contraseña no se guarde como texto plano
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import current_user, login_user, logout_user, login_required
from inicio import db
from .modelos import Usuario
from flask_login import UserMixin
from inicio import db
# --------------------------------- Modelo de bases de datos------------------------
# Hay que modificar la clase usuario para trabajar con la clase UserMixin de Flask-login
class Usuario(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
nombre_usuario = db.Column(db.String(15), unique=True)
correo_electronico = db.Column(db.String(50), unique=True)
contrasena = db.Column(db.String(80))
# ----------------------------------------------------------------------------------
"Esto es muy importante, hemos de revisar cualquier punto donde hayamos utilizado URL_FOR ya sea plantilla o archivo de python, como por ejemplo routes.py para que señale al blueprint donde se encuentra la vista a la que hace referencia".
Hacemos lo mismo para la vista signup. Cortamos y pegamos el código entero de la vista desde inicio.py hasta el directorio routes.py justo de bajo de la vista login que habíamos movido anteriormente.
Igual que antes, al desplazar el archivo desde la app principal al blueprint auth tenemos que modificar el decorador de la vista. También modificaremos todos los url_for que haya tanto en el código de la vista, como en la plantilla signup.html para que hagan referencia a los directorios donde se encuentran actualmente.
routes.py
Una vez realizado todo lo anterior realizamos exactamente los mismos pasos para la vista logout.
Para finalizar simplemente limpiamos el código en inicio.py que ya no se usa como por ejemplo métodos que existían al comenzar el capitulo pero que ahora ya no son necesarios al cortar y pegar el código a otros blueprint.
Al final ya tenemos un código manejable, funcional, que puede ser usado en otros programas o por varias personas que trabajen el proyecto de forma independiente.
Al terminal la estructura de directorios quedaría de la siguiente manera:
Archivo con los paquetes necesarios para ejecutar la aplicación.
(miEntorno) $ pip freeze > requirements.txt
El comando pip freeze volcará automáticamente toda la información sobre paquetes instalados y versiones en el archivo requirements.txt. De esta forma, si queremos recrear este mismo entorno virtual en otra máquina, lo único que tenemos que hacer es escribir:
(miEntorno) $ pip install -r requirements.txt
Con esto se instalará todo lo necesario para que pueda funcionar nuestro programa.
Y con esto terminamos el capitulo de los blueprint. Puedes ver el código completo terminado en el siguiente enlace:
Código del capítulo en github.
Próximo episodio. Desplegar una aplicación en Flask con Gunicorn y Nginx en una Rapsberry Pi.













