miércoles, 2 de septiembre de 2020

Flask 16. Mostrando mensajes en pantalla con el método Flash de Flask.

Fotos preguntas libres de regalías | Pxfuel


Anteriormente. Flask 15.Construyendo un Login de usuarios con Flask-login, Flask-WTForms, Flask-SQLALchemy y Flask-Bootstrap


Flash (con h no con k)

Es bueno que las aplicaciones y las interfaces de usuario reciban comentarios a las acciones que realicen los usuarios en ellas (feedback en inglés). 

Por ejemplo, imagina que utilizas el código del post anterior, que era para crear un sistema de login de usuarios. En el había un formulario para registrarse y otro para poder luego iniciar sesión. Imaginemos que el usuario ya se ha registrado pero que a la hora de loguearse no introduce bien la contraseña. 

Nos parece natural que en algún lugar de la pantalla aparezca un mensaje avisando de este hecho. Si no apareciese nada, el que lo esta utilizando no sabría si ha metido mal el nombre, el usuario, la contraseña o que sencillamente la aplicación no funciona.

En el post anterior esto lo solucionamos devolviendo una nueva página en la que si el nombre del usuario no existía en la base de datos, o bien existiendo,   la contraseña era incorrecta, nos mostraba un texto  que decía:



Pero estaría aún mejor, si en el propio formulario de login nos avisará de este error de esta forma:


Pues este mensaje y otros los podemos mostrar de una forma muy sencilla usando el método flash de Flask.

Utilizaremos el código del post anterior, del capitulo flask 15.

Partimos del archivo inicio.py. Como vamos a utilizar el método flash lo importaremos al principio del programa junto con todos los otros métodos que utilizamos de la librería de Flask.

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


Después en la vista login



vamos a cambiar el código dentro del rectángulo verde por este otro, para que se renderice el mensaje en la página del formulario directamente si el usuario o la contraseña es errónea:


        # mensaje a mostrar
        flash('El usuario no existe o la contraseña es incorrecta')
        # vista en la que se mostrará
        return redirect(url_for('login'))


Ahora en tenemos que incluir en la plantilla login.html, el código necesario para poder mostrar el mensaje. Lo más práctico es poner este código en un archivo aparte, para luego poder importarlo en la plantilla en la que lo necesitemos. No obstante también podrías poner directamente el código dentro del propio archivo en la zona donde quieras que aparezca. Yo utilizaré en este ejemplo el primer método.

Aquí quiero hacer un inciso general. Lo más cómodo sería colocar este código en una plantilla base de la que hereden todas las demás plantillas (como puede ser base.html). De esta forma tenemos una especie de rotulo, que estaría disponible en todas las plantillas y que muestre los mensajes que queramos mandar sin tener que escribir el código en cada una de ellas (lo que tampoco es complicado como veremos ahora). No obstante en este ejemplo vamos a utilizar otra opción.

Proseguimos. Ahora, creamos un archivo llamado _flash.html dentro de la carpeta "templates". El poner el _ delante del nombre es para saber que este archivo va a usarse dentro de otro, va a ser incluido en otra u otras plantillas. Este es el código con la estética más sencilla. Solo mostrará el texto que hemos preparado cuando se lance el evento. Sin embargo también se pueden hacer cosas mas complicadas con algo de css (texto que parpadea, se mueve etc)

Directorio de Trabajo
    |_ /static
    |_     |_ mystyle.css  
    |_ /templates
    |       |_ pagina_inicial.html 
    |       |_ signup.html 
    |       |_ login.html
    |       |_ _flash.html
    |_ /base_de_datos
    |_      |_ dbase.db
    |_ form.py 
    |_ inicio.py                                                                             
    |_ config.py           


<!-- Para mostrar un mensaje en una vista con flash''' -->

{% with mensajes = get_flashed_messages() %}
    {% if mensajes %}
        {% for mensaje in mensajes %}
            {{ mensaje }}
        {% endfor %}
    {% endif %}
{% endwith %}


Cuando llamemos a la función flash() dentro de la vista login, Flask guardará el mensaje, pero flashear el mensaje no hará que aparezca por arte de magia en las páginas web. La plantilla de la aplicación necesita "renderizar" este mensaje que hemos flasheado de forma que se funcione y se acople al diseño del sitio. Por eso tenemos que añadir este código en la plantilla que queramos que lo muestre.

Estamos usando el constructor with para asignar el resultado de la llamada a la función get_flashed_messages() a la variable que hemos llamado "mensajes", todo dentro del contexto de la plantilla. La función get_flashed_messages() hace una consulta a la aplicación de Flask y devuelve una lista con todos los mensajes que se hayan "flasheado" previamente. El condicional que sigue comprueba si la variable mensajes tiene algún contenido, y en este caso, se renderizará cada mensaje de la lista. 

Por contra, si es la primera vez que se entra en la plantilla o tanto el usuario como la contraseña del formulario de login son correctos el evento no se lanzará (no se ejecutará la sentencia) y por lo tanto la variable "mensajes" estará vacía y no se mostrará nada.

Una propiedad interesante de estos mensajes flash, al utilizar el constructor with, es que una vez que se solicitan los mensajes a través de la función get_flashed_messages(), estos se eliminan de la lista de mensajes, por lo que aparecen solo una vez después de llamar a la función flash.

Para incluir este código en la plantilla lo haremos con:

    {% include "_flash.html" %}


y como quiero que el mensaje aparezca después del botón de envío del formulario y antes de la frase "No tienes cuenta. Regístrate" lo coloco en login.html, en esta línea del código:





Ahora ya solo queda ejecutar el programa y ver que funciona.


Código del Capítulo


Próximo episodio. Manejo de Cookies en Flask.


No hay comentarios:

Publicar un comentario