<jupyter_start><jupyter_text>[![img/pythonista.png](img/pythonista.png)](https://www.pythonista.io)  Envío de mensajes al navegador.  La función ```flask.flash()```. Es posible enviar un mensaje al contexto de petición de una sesión activa mediante la función flash con la siguiente sintaxis:```flash(, category = )```Con esta función se envía un mensaje al cliente después de una petición para ser recibido en la siguiente petición. De igual manera y de forma opcional es posible enviar un segundo mensaje, indicando la naturaleza del mensaje principal mediante el parámetro *category*. Aún cuando se puede enviar cualquier cadena de caracteres para el parámetro *category*, se recomiendan las siguientes:* *'message'** *'warning'** *'error'** *'info'*  La función  ```get_flashed_messages()```.La función ```get_flashed_messages()``` captura los mensajes enviados por ```flash()```. Dicha función puede ser ejecutada desde una plantilla con la siguiente sintaxis:``` pythonget_flashed_messages(with_categories=, category_filter=[lista de objetos str])```Si se utiliza la función *get_flashed_messages()* sin argumentos, ésta capturará sólo el mensaje principal en vista de que el parámetro  *with_categories* tiene un valor por defecto de _False_.El parámetro *category_filter* indicará a la función la categoría de los mensajes que deberá capturar. Si no se indica nada, se capturarán todos los mensajes. **Ejemplo:**Se utilizará la aplicación del capítulo previo de captura de datos personales de un alumno y una vez que se ingresen los datos correctamente ocurrirá lo siguiente:* Se enviará un mensaje mediante la función *flash()* indicando que se ingresaron los datos correctamente.* Se recargará la URL correspondiente a la función de vista *altas()*.* Se desplegará el mensaje.La aplicación se desplegará desde http://localhost:5000/altas Se creó la plantilla [*templates/captura_alumno.html*](templates/captura_alumno.html) con el siguiente código.``` html Datos personales del alumno {% from "_formhelpers.html" import render_field %}    {{ form.hidden_tag() }}    {{ render_field(form.nombre) }}    {{ render_field(form.primer_apellido) }}    {{ render_field(form.segundo_apellido) }}    {{ render_field(form.carrera)}}    {{ render_field(form.semestre)}}    {{ render_field(form.promedio)}}    {{ render_field(form.alcorriente)}}        {{ form.enviar }}{% with mensajes = get_flashed_messages() %}  {% if mensajes %}        {% for mensaje in mensajes %}        {{ mensaje }}    {% endfor %}      {% endif %}{% endwith %}```**Advertencia:** Una vez ejecutada la siguiente celda, es necesario interrumpir el kernel de Jupyter para poder ejecutar el resto de las celdas de la notebook.<jupyter_code>from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, BooleanField, SelectField
from wtforms.validators import DataRequired, ValidationError
from flask import Flask, render_template, flash, redirect, url_for, abort

carreras = (('Derecho', 'Derecho'), ('Medicina', 'Medicina'), ('Sistemas', 'Sistemas'), ('Diseño', 'Diseño'))

        
class DatosEstudiante(FlaskForm):

            
    def valida_promedio(form, field):
        try:
            numero = float(field.data)
        except:
            raise ValidationError('Debe de ingresar un número')
        if numero < 0 or numero > 10:
            raise ValidationError('Debe de ingresar un número entre 0 y 10')        
            
            
    nombre = StringField('Nombre', [DataRequired()], default = '')
    primer_apellido = StringField('Primer apellido', [DataRequired()], default = '')
    segundo_apellido = StringField('Segundo apellido', default = '')
    carrera = SelectField('Carrera', [DataRequired()], choices = carreras)
    semestre = SelectField('Semestre', [DataRequired()], choices = [(str(x), str(x)) for x in range(1, 50)])
    promedio = StringField('Promedio', [DataRequired(), valida_promedio], default = '0')
    alcorriente = BooleanField('Al corriente de pagos')
    enviar = SubmitField('Enviar')
    
            
app = Flask(__name__)
app.config['SECRET_KEY']='Saludines'



@app.route('/altas', methods=['GET', 'POST'])
def altas():
    bandera = True
    forma = DatosEstudiante()
    if  forma.validate_on_submit():
        flash('Datos ingresados correctamente')
        for campo in ['nombre', 'primer_apellido', 'segundo_apellido', 'carrera',
                     'semestre', 'promedio', 'alcorriente']:
            print(forma[campo].data) 
        return redirect(url_for('altas'))
    return render_template('captura_alumno.html', form=forma)

#Si no se define el parámetro host, flask sólo será visible desde localhost
# app.run(host='localhost')
app.run('0.0.0.0')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11538461538461539, 'fraction_numerical': 0.0038038884192730348, 'mean_word_length': 4.421534936998855, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '426108', 'license': 'MIT', 'n_tokens_mistral': 1517, 'n_tokens_neox': 1494, 'n_words': 455, 'path': '12_mensajes_al_navegador.ipynb', 'repo_name': 'davidrodord56/py221', 'size': '4732'}