Mostrando entradas con la etiqueta flask blueprint español. Mostrar todas las entradas
Mostrando entradas con la etiqueta flask blueprint español. Mostrar todas las entradas

lunes, 12 de octubre de 2020

Flask 19. Usar Flask Blueprint para estructurar aplicaciones. Parte 2ª..

 



Usar Flask Blueprint para estructurar aplicaciones. Parte 2ª.


Siguiendo con el punto anterior, se dice que hay dos formas de organizar un proyecto, mediante una división Estructural o bien mediante una división Funcional.

División Estructural.


En una división Estructural, el código se agrupa basandonos en lo que hace dentro del programa. Es decir, se agrupan por ejemplo los archivos de vistas, de un lado, las plantillas por otro, el contenido estático, los formularios y así sucesivamente.

La estructura típica de esta división sería la siguiente:


+ directorio_de_trabajo/
   |_ app/
      |_ __init__.py
      |_ static/
      |_ templates/
         |_ public/
            |_ index.html
            |_ ...
         |_ users/
            |_ login.html
            |_ sign_up.html
            |_ ...
         |_ private/
            |_ index.html
         |_ ...
      |_ rutas/
         |_ __init__.py
         |_ private.py
         |_ public.py
         |_ users.py
         |_ ...
      |_ modelos/
         |_ users.py
         |_ ...
      |_ formularios/
         |_ users.py
         |_ ...
   |_ inicio.py
   |_ requirements.txt
   |_ ...


División Funcional.


Por el contrario en una división funcional, los diferentes componentes del código se van a agrupar en base a lo que hacen o para lo que se utilizan en la aplicación. Así todas las vistas, plantillas, modelos, formularios etc de una parte que tienen una relación común en la aplicación se agrupan dentro de un mismo paquete.

La estructura típica de esta división sería la siguiente:

+ directorio_de_trabajo/
   |_ app/
      |_ __init__.py
      |_ publico/
         |_ __init__.py
         |_ routes.py
         |_ static/
         |_ templates/
         |_ models.py
         |_ forms.py
         |_ ...
      |_ privado/
         |_ __init__.py
         |_ routes.py
         |_ static/
         |_ templates/
         |_ models.py
         |_ forms.py
         |_ ...
      |_ usuarios/
         |_ __init__.py
         |_ routes.py
         |_ static/
         |_ templates/
         |_ models.py
         |_ forms.py
         |_ ...
      |_ ...
      |_ static/
      |_ templates/
   |_ inicio.py
   |_ requirements.txt
   |_ ...


Para ver como aplicar esto que hemos visto, vamos a utilizar el código del capítulo 15 "Login de Usuarios" que puedes encontrar en esta dirección del repositorio de github. Utilizaremos en él un modelo funcional, aunque realmente el diseño del proyecto  puedes hacerlo tu como quieras, de la forma que se adapte a tus necesidades.

Al utilizar una división funcional, agruparemos los diferentes elementos en tres bloques. El bloque principal será el que tiene que ver con las funciones de autentificación del usuario (login, registro y log-out), otro bloque contendrá las páginas que son públicas (en el ejemplo solo la página inicial) y un último bloque con la página a a la que se accede una vez el usuario se ha logeado (dashboard).


Bloque de páginas públicas (En nuestro caso solamente la pagina_inicial)


Si abrimos el proyecto del capítulo 15, verás que tiene la siguiente estructura de directorios:



Empecemos a trabajar creando un nuevo directorio, dentro del directorio de trabajo y al nivel de la aplicación principal. Este archivo lo puedes llamar como quieras, yo lo llamaré app y contendrá todo el contenido de la aplicación.

Vamos a ir paso a paso. Dentro de este directorio, app, crearemos un archivo vacío llamado __init__.py para que python considere este directorio como un paquete y podamos importar diferentes recursos de ella. 

Lo más sencillo es empezar creando el blueprint para la parte pública de la aplicación. Recordemos que esta parte pública contendrá, en nuestro caso, la vista y la plantilla de la pagina_inicial o de bienvenida que es la que puede ver todo el mundo. 

Dentro del directorio app, creamos también el directorio public donde meteremos todo lo que hemos dicho en el párrafo anterior. Aquí dentro también creamos un nuevo archivo __init__.py

Para usar un blueprint siempre seguiremos los mismos pasos:

"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:

from flask import Blueprint

public = Blueprint('public', __name__, template_folder='templates')

from . import routes

 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

from flask import render_template
from . import public

@public.route('/')
def home():
    return render_template('pagina_inicial.html')

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:

# importamos y registramos los blueprint
from app.public import public
app.register_blueprint(public)

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)


Por seguir con cosas fáciles, vamos ahora a preparar la parte a la que se podía acceder una vez que el usuario se había logeado en la aplicación. Estrictamente hablando, en esta parte ni siquiera se renderizaba una plantilla, tan solo la vista devolvía un mensaje por pantalla en el que se mostraba el siguiente texto "Bienvenido {}, esta es la página de control a la que se puede acceder si estas registrado"

Creamos un directorio llamado private dentro del directorio app.

directorio_trabajo/app/private

Seguimos los mismos pasos que en el punto anterior y creamos el archivo __init__.py en donde crearemos el blueprint "private" y cargaremos las rutas del mismo.

from flask import Blueprint
private = Blueprint("private",__name__)
# como no tiene de momento plantillas no usamos template_folder
from . import routes

A continuación, al mismo nivel creamos el archivo routes.py

directorio_trabajo/app/private/routes.py


from . import private
from flask_login import login_required, current_user

@private.route('/dashboard/')
# decorador para que no se pueda entrar en la vista si no estas logeado
@login_required
def dashboard():
    return '''<h2>Bienvenido {},esta es la pagina de control <br/> a la que se puede acceder 
    si estas registrado.</h2>
    <br />
    <a href="/">Volver</a> 
    '''.format(current_user.nombre_usuario)

Importamos el blueprint "private" y los módulos login_required y current_user de flask_login.

Hacemos un corta y pega de la vista /dashboard/ del archivo inicio.py en este archivo routes.py.

En el definíamos la función que va a definir la vista de la página privada (dashboard). Como es una página simple no se renderiza un archivo html sino que retornamos directamente un texto en formato html. Al tratarse de un ejemplo sencillo esta parte del código no tiene más vistas y por tanto es la única a la que se puede acceder cuando el usuario se haya logeado.

Para finalizar registramos el blueprint en la aplicación principal.



Bloque relacionado con las funciones de autentificación de usuarios.


Nos pondremos ahora con la parte de la aplicación que cuya función es registrar a los usuarios, logearlos y posteriormente realizar la desconexión. El proceso es el mismo que en puntos anteriores pero con algunas modificaciones que tenemos que realizar en el tema de las plantillas.

Comenzamos creando el directorio que contendrá todos los archivos y el código. Yo lo voy a llamar "auth" y estará en el directorio:

Directorio_de_trabajo/app/auth

y dentro creamos el archivo __init__.py donde definiremos el blueprint.

Directorio_de_trabajo/app/auth/__init__.py

from flask import Blueprint
auth = Blueprint('auth', __name__, template_folder="templates")
from . import routes
El código es igual que los anteriores. 

Comenzamos importando el método Blueprint de Flask (auth). 

Definimos el objeto blueprint "auth" que tendrá una carpeta al mismo nivel para almacenar las plantillas de sus vistas que llamaremos "templates". Esta carpeta es propia de este directorio y solo la van a usar las plantillas del grupo auth. 

Aunque todavía no hemos creado el archivo routes.py, que contendrá las rutas de las diferentes vistas, lo importamos para finalizar este archivo.

Creamos la carpeta "templates" en:

Directorio_de_trabajo/app/auth/templates

Para a continuación cortar y pegar todas las plantillas que estaban en:

Directorio_de_trabajo/templates a este nuevo directorio.

(login.html, signup.html y flask.html). Luego tenemos que hacerlas unas pequeñas modificaciones.

Seguimos registrando el blueprint en la aplicación principal inicio.py:



Ahora, creamos al mismo nivel el archivo routes.py que contendrá las vistas de este grupo.

Punto primero, importamos el blueprint:

 1. from . import auth

Seguimos trasladando de inicio.py todo lo relacionado con el inicio de sesión en el sistema de los usuarios, que era la vista 'login'.

Como esta parte es la más laboriosa, que no complicada, vamos a y ir explicándola muy despacio.

Nos vamos a inicio.py y cortamos y pegamos todo el código de la vista login en el archivo routes.py
Date cuenta de que en el código el decorador para la vista login no es @app.route(...) sino que como está en el blueprint auth tiene que ser @auth.route(...)

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)

Si tal como esta el proyecto ahora mismo lo ejecutamos, nos dará el siguiente error, nada más cargar la página principal.


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"

Para ir dejándolo todo arreglado también modificaremos los enlaces para signup y logout, como puedes ver en la imagen inferior.



Al haber desplazado archivos se nos siguen produciendo errores. Si ejecutáramos en el programa la vista de login nos daría este error:


Esto se debe a que la vista esta usando un objeto que aun no hemos especificado  en este archivo y tampoco hemos movido el método que lo genera. En otras palabras, tenemos que cortar y pegar el archivo form.py que está en el directorio principal al directorio "auth", además de importar el objeto en el archivo routes.py.

 1 from . import auth
 2 from .form import Formulario_de_Login

Lo mismo nos va a ocurrir con unas cuantas cosas que estaban definidas o cuyo código estaba en inicio.py y que ahora tenemos que trasladar a routes.py para que funcionen sus vistas. Para no extendernos demasiado voy a poner el código de todo lo que hay que trasladar:

routes.py

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
 

El último punto de este código hace referencia a la importación del objeto Usuario que va a estar dentro del archivo que vamos a crear a continuación en este mismo directorio, modelos.py. Contendrá la parte del código que gestionaba o mejor dicho definía la estructura del objeto usuario. En el se gestionaba la estructura de la base de datos donde guardamos el nombre, correo electrónico y contraseña de los usuarios que se registraban en nuestra aplicación.

Lo único que tenemos que hacer es crear el archivo modelos.py y cortar y pegar el código siguiente que hasta ahora se encontraba en nuestra aplicación principal, inicio.py.

modelos.py

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))


# ----------------------------------------------------------------------------------

Importante: este objeto Usuario es utilizado por en el cargador de Usuarios en Flask Login. Al haber desplazado el código de la aplicación principal a app/auth/modelos.py tenemos que importar el objeto Usuario previamente añadiendo lo siguiente al código en inicio.py:



Además, como dijimos anteriormente, tenemos que modificar los url_for que hay en la plantilla login.html para que hagan referencia a donde se encuentra ahora, después de moverlas, la vista a la que hacen referencia:

login.html



"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.


A estas alturas del curso de Flask, ya hemos instalado bastantes paquetes dentro de nuestro entorno virtual. Si alguna vez tenemos que volver a ejecutar este entorno en otro máquina, de memoria, seguro que tendríamos problemas para recordar que paquetes instalamos, por lo que la práctica generalmente aceptada para evitar este problema es escribir un archivo llamado requirements.txt. Este archivo estará en la carpeta raíz de nuestro proyecto, e indicara todas las dependencias o paquetes que necesita el proyecto para funcionar, junto con sus versiones.

¿Y esto como se hace te preguntarás? Pues realmente es muy fácil. 

(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.






jueves, 10 de septiembre de 2020

Flask 18. Usar Flask Blueprint para estructurar las aplicaciones. Parte 1ª




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.


+ nuestra_aplicación
|_ inicio.py
|_ static/
|_ templates/


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

from flask import Blueprint, render_template

# recomendacion: poner el mismo nombre a la variable que el archivo o directorio que contenga
# el Blueprint
segunda = Blueprint("segunda", __name__, static_folder="static", template_folder="templates")
# static _folder y template_folder son opcionales

@segunda.route('/')
@segunda.route('/home/')
def home():
    return render_template('home.html')

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
Pues bien, para importar el objeto blueprint que hemos creado, y que se llama segunda, dentro de nuestro programa principal, le decimos al programa: " Importa desde el módulo segunda el objeto segunda ":

from segunda import segunda

Y una vez registrada la aplicación principal "app" registramos nuestras mini-aplicaciones o blueprints con:

app.register_blueprint(segunda)

Quedando el código de principal.py de la siguiente forma:

from flask import Flask
# importamos el blueprint
from segunda import segunda

app=Flask(__name__)
# Lo registramos una vez creada la aplicación principal
app.register_blueprint(segunda)

@app.route('/')
def test():
    return "<h1>Prueba</h1>"

if __name__=="__main__":
    app.run(debug=True)


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:



Esto se produce al entrar en conflicto las dos aplicaciones ya que ambas tienen el mismo nombre de vista ...route('/'). Para evitar esto y hacer que cada aplicación pueda tener vistas independientes vamos a usar el parámetro url_prefix al definir el blueprint. Simplemente añade esto al código:

from flask import Flask
# importamos el blueprint
from segunda import segunda

app=Flask(__name__)
# Lo registramos una vez creada la aplicación principal
app.register_blueprint(segunda, url_prefix="/admin")

@app.route('/')
def test():
    return "<h1>Test</h1>"

if __name__=="__main__":
    app.run(debug=True)


Con esto conseguiremos que nuestro blueprint empiece a funcionar cuando se acceda a la vista con prefijo /admin. Más concretamente a 127.0.0.1:5000/admin. En este caso @segunda.route("/") hace que se renderice el archivo home.html cuando vayamos a la vista inicial del blueprint que es la que ya comentamos, 127.0.0.1:5000/admin.  Y lo mismo ocurre si acedemos a la url 127.0.0.1:5000/admin/home


Vista para 127.0.0.1:5000/admin e 127.0.0.1:5000/admin/home





Sin embargo si ahora tecleas 127.0.0.1:5000/ si que veras el texto "prueba"





Hay otros argumentos opcionales que puedes proporcionar para modificar el comportamiento del Blueprint. Repasemos los que ya conocemos y veamos algunos nuevos:

static_folder: la carpeta donde se pueden encontrar los archivos estáticos del Blueprint

static_url_path: la URL desde la cual servir archivos estáticos.

template_folder: la carpeta que contiene las plantillas del Blueprint

url_prefix: la ruta para anteponer a todas las URL del Blueprint

subdomain: el subdominio con el que las rutas de este Blueprint coincidirán de forma predeterminada

url_defaults: un diccionario de valores predeterminados que recibirán las vistas de este Blueprint

root_path: la ruta del directorio raíz del Blueprint, cuyo valor predeterminado se obtiene del nombre de importación del Blueprint

Ten en cuenta que todas las rutas, excepto root_path, son relativas al directorio del Blueprint.

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í:


from flask import Flask
# importamos el blueprint
from app.admin.segunda import segunda

app=Flask(__name__)
# Lo registramos una vez creada la aplicación principal
app.register_blueprint(segunda, url_prefix="/admin")

@app.route('/')
def test():
    return "<h1>Test</h1>"

if __name__=="__main__":
    app.run(debug=True)


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.


Código del capítulo.


Próximo Episodio: Flask 19. Usar Flask Blueprint para estructurar las aplicaciones. Parte 2ª