Nuestra primer aplicación en flask – Tutorial (Parte 4) – Jinja2

jinja2¡Bienvenidos, en la entrada anterior terminamos de crear nuestro modelo y ha llegado el momento de conectarlo con el controlador y la vista donde mostraremos los elementos usando Jinja2!. Para ello:

  1. Importaremos el modelo al controlador..
  2. Desde el controlador llamaremos los métodos de la clase Persona creada en el modelo según el tipo de solicitud o acción realice el cliente.
  3. Aprenderemos y usaremos la sintaxis de Jinja2 para mostrar variables y ejecutar instrucciones dentro de nuestro template. De esta forma estaremos conectado modelo con controlador y controlador con vista.

 

En este último post vamos a tratar de terminar con nuestra aplicación y hacer un repaso por los pasos realizados!

Bien, vamos a ver el código de nuestro modelo.py:

#BLOQUE IMPORT
import os
import json

#BLOQUE APERTURA ARCHIVO JSON

THIS_FOLDER = os.path.dirname(os.path.abspath(__file__))
my_file = os.path.join(THIS_FOLDER + '/DB/' 'base_de_datos.json') 

# --> Función Leer archivo JSON   
def leer_json():
    with open (my_file, "r") as f:
        datos = json.load(f)
        f.close()
        return datos
datos = leer_json()

# --> Función modificar JSON
def modificar_json():
    with open (my_file, "w") as modid:
            json.dump(datos, modid, indent=4)
            modid.close()


#BLOQUE CLASE PERSONA Y CRUD
class Persona(object):
    contador_id = datos["Configuraciones"][0]["contador_id_db"]

    def __init__(self, nombre, apellido, apodo, telefono, direccion):
        print("El contador está en: ", Persona.contador_id)
        self.id = Persona.contador_id #Atriuto id es igual a la variable
        self.nombre = nombre
        self.apellido = apellido
        self.apodo = apodo
        self.telefono = telefono
        self.direccion = direccion

    #Método CREATE -> Crear una nueva persona o contacto de la base de datos
    def crear_contacto(self):    
            datos["Configuraciones"][0]["contador_id_db"]+=1 #Cambiamos el valor de "contador_id_db" (en la base de datos)
            modificar_json()
            print("El contador está ahora en: ", datos["Configuraciones"][0]["contador_id_db"])
            Persona.contador_id +=1 #Sumamos uno a la variable contador_id de la clase
        #Creamos nueva instancia
            nueva_persona = Persona(
                self.nombre,
                self.apellido,
                self.apodo,
                self.telefono, 
                self.direccion).__dict__ #Guardamos la nueva persona es decir "instancia" dentro de la variable "nueva_persona" como DICCIONARIO
            datos['Personas'].append(nueva_persona) #->Entramos a los valores de la clave "Personas" que son Lista y añadimos el nuevo objeto (diccionario)
            modificar_json()

    #Método READ -> Leer una persona o contacto de la base de datos
    def leer_contacto(atr, valor):
        encontradas = {} #Creamos un diccionario para almacenar los resultados

        for persona in datos["Personas"]: #Cada "indice" es un diccionario de persona
            if persona[atr] == valor: #Si el atributo de ese diccionario es igual al que pasamos


                #Obtenemos el indice de esa persona
                indice = datos["Personas"].index(persona) #La variable toma el valor de la posición de la persona

                #Guardamos en el diccionario nuevo
                encontradas[indice] = persona #Se añade cada persona encontrada con index como clave

        return (encontradas) #Retornamos los datos encontrados

    
    #Método UPDATE -> Actualizar o modificar un dato de algún contacto en la bd
    def actualizar_contacto(id, atr, nuevo_valor):
        for persona in datos["Personas"]: #Cada "indice" es un diccionario de persona
            if persona["id"] == id: #Si el "id" de ese diccionario es igual al arguemento id
                print (persona) #Imprime el diccionario
                
                #Obtenemos el indice de esa persona
                indice = datos["Personas"].index(persona) #La variable toma el valor de la posición de la persona
                datos["Personas"][indice][atr] = nuevo_valor #Accedemos a ese diccionario> clave y cambiamos su valor
                print (datos["Personas"][indice][atr]) #Imprimimos para confirmar el cambio en "datos" (lectura)
                modificar_json()
            

    #Método DELETE -> Borrar una persona o contacto de la base de datos
    def eliminar_contacto(id):
        for persona in datos["Personas"]: #Cada "indice" es un diccionario de persona
            if persona["id"] == id: #Si el "id" de ese diccionario es igual al arguemento id
                print ("Se va a borrar: ", persona) #Imprime el diccionario
                
                #Obtenemos el indice de esa persona
                indice = datos["Personas"].index(persona) #La variable toma el valor de la posición de la persona
                datos["Personas"].pop(indice) #Borramos usando el método de listas .pop()
                modificar_json()

 

Importar el modelo al controlador

Antes de comenzar a usar o llamar métodos del modelo desde el controlador, debemos importarlo!. Para ello lo podemos hacer de las siguientes maneras; en el controlador:

from models import Persona

Ahora vamos a recordar el código de nuestro controlador ya que lo primero será trabajar con las solicitudes que nuestro controlador va a aceptar y que método del modelo deberá llamar.

Código de controlador.py:

from flask import Flask, request, render_template #Importamos clase Flask, objeto request de flask (librería)
app = Flask(__name__) #Creamos una app instanciando la clase Flask (automáticamente el nombre de la app)
from models import Persona #IMPORTAMOS EL MODELO
#Rutas - (argumentos: Url) - Función

@app.route('/', methods = ['GET', 'POST']) #Decoramos con método de app que es una instancia de la clase Flask y argumentamos "slash"
def inicio(): #Definimos una función llamada Inicio
    if request.method == 'POST':
        pass
    else:
        return render_template('/index.html') #Retornornamos el template usando RENDER_TEMPLATE()

@app.route('/agradecimiento', methods = ['GET']) #Decoramos con método routes la próxima función arguementando la url "/agradecimiento"
def agradecer(): #Definimos una función llamada agradecer
    return 'Gracias pythones.net!' #Retorno de la función

#Iniciar app

if __name__ == '__main__': #Condicional de que si la aplicación ejecutada se coincide al nombre de la aplicación
    app.run('127.0.0.1', 5000, debug=True) #Método que inicia la app con la dirección, puertos y modo de argumentos

 

La página de inicio de nuestra app

Recordemos que nuestro controlador carga un template html al inicio de nuestra aplicación. Es momento de comenzar a enlazar la vista con el controlador y este con el modelo.

La página de inicio al ser cargada debería automáticamente cargar las personas que tenemos almacenadas en la base de datos dentro de la barra lateral derecha. Esto sería responder a una solicitud GET, es decir, el cliente estará solicitando obtener datos al momento de cargar nuestro sitio web.

 

¿Cómo listamos los elementos de la base de datos JSON en nuestra plantilla index.html?

Bueno recordarás que en el models.py declaramos el método «leer_contacto()» que obtenía como argumento el nombre del atributo y el valor para devolvernos una persona. Pues básicamente lo que podemos hacer es que al momento de una solicitud GET en nuestra página de inicio se llame a este método con el argumento «all» para que devuelva un diccionario de todas las personas que tenemos almacenadas en la base de datos y finalmente nosotros se lo pasemos como argumento en una variable a la vista usando la función «render_template()«. Luego ya desde la vista nos encargamos de manejar y listar los elementos de ese diccionario. Así que a ello:

  1. Llamar al método del modelo leer_contacto() desde el controlador respondiendo solicitud GET.
  2. El valor que nos retorne el método del modelo debemos almacenarlo en una variable y enviarlo en la función «render_template()» como argumento.
  3. Desde la vista debemos desplegar este elemento usando Jinja2.

Para el primer  y segundo paso; recordemos que teníamos un condicional que comprobaba el tipo de solicitud realizada, PERO NO LO VAMOS A NECESITAR, ya que solo aceptaremos solicitudes GET así que solo añadimos la llamada al método leer_contacto() y borraremos lo demás:

from flask import Flask, request, render_template #Importamos clase Flask, objeto request de flask (librería)
app = Flask(__name__) #Creamos una app instanciando la clase Flask (automáticamente el nombre de la app)
from models import Persona


#Rutas - (argumentos: Url) - Función

@app.route('/', methods = ['GET']) #Decoramos con método de app que es una instancia de la clase Flask y argumentamos "slash"
def inicio(): #Definimos una función llamada Inicio
    #Llamamos al método para listar personas y lo almacenamos en "Todos"
    Todos = Persona.leer_contacto('id', 'all') 

    return render_template('/index.html', Todos = Todos) #Retornornamos el template + Todos

@app.route('/agradecimiento', methods = ['GET']) #Decoramos con método routes la próxima función arguementando la url "/agradecimiento"
def agradecer(): #Definimos una función llamada agradecer
    return 'Gracias pythones.net!' #Retorno de la función

#Iniciar app

if __name__ == '__main__': #Condicional de que si la aplicación ejecutada se coincide al nombre de la aplicación
    app.run('127.0.0.1', 5000, debug=True) #Método que inicia la app con la dirección, puertos y modo de argumentos

Aquí estamos llamando el template «index.html» como habitualmente lo hacemos pero también pasando el argumento «Todos» que nos devuelve el modelo. Tal como se indica debemos pasar el nombre y el valor. El cual contiene un diccionario con todos las personas de la base de datos.

Ahora debemos listar este contenido en la vista, en el apartado dentro de index.html que creamos para ello. Así que abrimos este archivo HTML:

Ejecutar código python en html con flask

Pero antes será mejor que aprendamos lo siguiente, rápidamente:

 

Motor de plantillas Jinja2 – Ejecutar código Python en los archivos HTML

Anteriormente en otro post redacte acerca del motor Jinja2 que es la librería que utiliza FLASK para renderizar las plantillas y nos permite incluir código Python dentro del HTML siguiendo ciertas «normas de escritura o reglas de interpretación». Las cuales trataré de resumir de forma breve pero puedes encontrar más información leyendo la Documentación oficial de dicha librería; una práctica a la que deberías habituarte.

Estoy debiendo un post completo de Jinja2 pero lo haré al final como un resumen de todo FLASK.

Variables en Jinja2 – ¿Cómo creamos y mostramos una variable?

Acaremos primero:

  • Toda variable a mostrar debe ser pasada como argumento en la función render_template siguiendo la siguiente estructura: render_template(‘archivo_html’, var = valor) donde var corresponde a la variable y valor a su asignación.
  • Si la variable no es pasada como argumento entonces deberá ser creada en el template mismo usando el motor Jinja2 mediante «set«.
  • No podemos incluir variables si no son creadas o importadas en la renderización del template.

Dicho esto:

Mostrar variables

Para mostrar una variable usamos {{ var }} donde var es el nombre de la variable pasada como argumento o creada antes.

Crear una o múltiples variables

Para crear variables y asignarles algún valor dentro del mismo template simplemente usamos «set» así:

  • {% set var = «texto» %} #Creamos una variable llamada «var» con el contenido «texto»
  • {% set var1, var2 = «texto1», «texto2» %} #Creamos dos variables «var1» y «var2» con el respectivo contenido: en var1 = «texto1» y en var2 = «texto2»

Ejecutar instrucciones de código Python – Funciones, bucle for y condicionales

Para el caso de las instrucciones siempre utilizamos «{%» para abrir cada elemento de la instrucción y «%}» para cerrar. Excepto en el caso de las funciones.

Funciones en jinja2

Las funciones se deben (al igual que las variables) pasar como argumentos o bien crear dentro del template, para pasarlas como argumentos se deben pasar los valores para los parámetros y luego el nombre de la función en render_template() así: return render_template(‘sumar.html’, val1=10, val2=30, funcion=suma) donde suponemos una función suma() sencilla que admite dos parámetros para sumar dos números en el controlador. Y luego en la vista la podemos llamar así:

  • {{ funcion(val1, val2) }} #Llamamos la función suma que admite 2 parámetros que toman como valor por defecto los que pasamos en render_template()
  • Si quisiéramos cambiar los valores de val1 y val2 para sumar otros números diferentes a los pasados como argumento en render_template() lo hacemos así:
    • {% set val1 = 55 %}  #Seteamos el valor de «val1» a 55
      • Y finalmente sumamos nuevamente:
      • {{ funcion(val1, val2) }}

Condicionales en Jinja2 – IF, ELIF, ELSE

Tanto en el caso de los condicionales como en el de los ciclos o bucles la sintaxis Jinja2 aplica solo al código Python, y aclaro esto porque cuesta acostumbrarse. Pero cada bloque IF o bucle FOR debe abrirse y cerrarse como si de una etiqueta HTML se tratara, por ejemplo:

  • {% if (1 + 1) = 2 %} #Abrimos un bloque condicional
    • print(«La suma de 1 + 1 es 2») #Python
  • {% else %} #El else se coloca igual que el if pero no se cierra
    • print(«No se cumple la condición») #Python
  • {% endif %} #Cierre del bloque if

Bucle for

Jinja2 solo nos permite el bucle «for», cuya sintaxis es semejante a los condicionales o bloques if, elif, else. Abrimos el bloque y luego lo cerramos. Y se me olvidaba comentar que obviamente puedes colocar HTML dentro de cualquiera de estos bloques así como también incluir otros archivos HTML. Veamos el bucle FOR:

  • {% for val in [1,2,3,4,5,6,7,8,9] %} #Apertura de bucle for itera lista
    • {{ val }} #Muestra el contenido
  • {% endfor %} #Cierre del bucle for

Mostrar elementos dentro de nuestra plantilla index.html

Ahora que hemos aprendido la sintaxis de Jinja2 es momento de aplicarlo. En nuestra plantilla index debemos listar cada persona almacenada en la base de datos pero incluyendo en cada elemento los 3 botones que diseñamos para «Ver, Modificar, Borrar» por ello el bucle for debe incluirlos en cada iteración de la siguiente manera:

Podemos usar un bucle for para iterar el diccionario «Todos» así:

<div style="width: 20%; float:right; margin-right: 10%; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><button name = "ver">Ver</button></td><!--Columna que mostrará el botón Ver-->
                    <td><button name = "editar">Editar</button></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><button name = "agregar">Agregar</button></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>

Esto nos devolverá algo así en nuestro index.html:

Listar elementos en html jinja2

Como ves estamos listando las personas y se corresponden los 3 botones para cada una de ellas. El problema es que estéticamente se ve horrible porque además nos está listando todos los datos de cada persona, y nosotros solo queríamos mostrar el Nombre. Para ello debemos modificar nuestro código especificando solo la clave que queremos mostrar así:

Código completo archivo index.html:

<!DOCTYPE html>
<html lang="es"> <!--Cambiamos a español-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primer App en Flask</title> <!--Modificamos el Título-->
</head>
<body><!--Aquí comienza el cuerpo de nuestro HTML-->

    <h1 style = "text-align:center">Directorio Telefónico - Mi primer aplicación en Flask</h1> <!--Titulo principal centrado-->
    <br>

    <div>    <!--Creamos un div contenedor-->
        <div style="width: 60%; float:left; text-align:center;">    <!--Creamos el div de la izquierda-->
            <h2>Datos completos de la persona</h2>  <!--Titulo-->
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>

                </tr>
                <tr><!--creamos otra fila-->
                    <td></td> <!--Aquí se cargarán los datos correspondientes-->
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </table>    <!--Fin de la tabla-->
        </div>  <!--Cierre del div de la izquierda-->

        <div style="width: 40%; float:right; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona.nombre}}, {{persona.apellido}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><button name = "ver">Ver</button></td><!--Columna que mostrará el botón Ver-->
                    <td><button name = "editar">Editar</button></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><button name = "agregar">Agregar</button></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>
    </div>
</body>
</html>

 

Y este será el resultado:

Listar elementos usando jinja2

Ahora nos quedaría añadir a cada uno de los botones la llamada al método correspondiente!.

Botones de acción en nuestro template index.html

En el bucle for anterior he accedido al «index» como la clave y asignado cada respectivo valor a «persona«. Entonces en cada botón podremos usar el número de «index» para llamar al método dependiendo la persona a la que corresponde ese botón presionado. Lo verás a continuación:

 

El botón «Ver» – Mostrar elementos (GET) – READ

En el caso de este botón es realmente sencillo ya que solo estaremos solicitando información al servidor mediante GET e intentaremos mostrarla en nuestro divisorio de la derecha. Como ya tenemos cargados los elementos en la variable «Todos» simplemente podríamos utilizar el numero de index del elemento y mostrar sus valores según el atributo de la persona. Pero para ello, debemos:

  1. Crear un bucle for similar al anterior en «index.html» que compruebe mediante un condicional el número de index pasado como argumento con el diccionario «Todos» y muestre los datos del elemento en cuestión.
  2. Crear una url dinámica que nos permita pasar el numero de index del elemento a mostrar como argumento.
  3. Mediante el botón «ver» debemos redirigir al cliente a esa ruta seguido del número de index.
Aclaración!
Aquí bien podríamos crear un include usando jinja2 y trabajar de otras muchas maneras que nos simplificarán las cosas. Pero intento explicar de forma que el lector avance en conocimientos gradualmente.

Como primer paso, nos bastaría con utilizar un bucle for similar al anterior pero esta vez introduciendo un condicional que compruebe una variable «index_ver» que se corresponderá al index de la persona o elemento de la lista que queremos mostrar. Algo así:

<!DOCTYPE html>
<html lang="es"> <!--Cambiamos a español-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primer App en Flask</title> <!--Modificamos el Título-->
</head>
<body><!--Aquí comienza el cuerpo de nuestro HTML-->

    <h1 style = "text-align:center">Directorio Telefónico - Mi primer aplicación en Flask</h1> <!--Titulo principal centrado-->
    <br>

    <div>    <!--Creamos un div contenedor-->
        <div style="width: 60%; float:left; text-align:center;">    <!--Creamos el div de la izquierda-->
            <h2>Datos completos de la persona</h2>  <!--Titulo-->
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>

                </tr>
                {% for (index, persona) in Todos.items() %}
                {% if index == index_ver %}
                <tr><!--creamos otra fila-->
                    <td>{{persona.nombre}}</td> <!--Aquí se cargarán los datos correspondientes-->
                    <td>{{persona.apellido}}</td>
                    <td>{{persona.apodo}}</td>
                    <td>{{persona.telefono}}</td>
                    <td>{{persona.direccio}}</td>
                </tr>
                {% endif %}
                {% endfor %}
            </table>    <!--Fin de la tabla-->
        </div>  <!--Cierre del div de la izquierda-->

        <div style="width: 40%; float:right; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona.nombre}}, {{persona.apellido}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><button name = "ver">Ver</button></td><!--Columna que mostrará el botón Ver-->
                    <td><button name = "editar">Editar</button></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><button name = "agregar">Agregar</button></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>
    </div>
</body>
</html>

Ahora para ejemplificar si en nuestro controlador en la función render_template() pasamos un valor entero a la variable «index_ver» por ejemplo «0» (cero) mostrará el nombre de la persona cuya clave es «0» en el diccionario «Todos«.  (Aclaración: en el bucle for estamos iterando un diccionario por el par Clave : Valor donde el «index» es la clave, y valor «persona»). Ejemplo:

@app.route('/', methods = ['GET']) #Decoramos con método de app que es una instancia de la clase Flask y argumentamos "slash"
def inicio(): #Definimos una función llamada Inicio
    #Llamamos al método para listar personas y lo almacenamos en "Todos"
    Todos = Persona.leer_contacto('id', 'all') 
    return render_template('/index.html', Todos = Todos, index_ver = 0) #Retornornamos el template + Todos

 

Si pasamos el valor «0» se mostrará:

Ejemplo

Así que vamos por el camino correcto, podríamos creer ahora que solo nos faltaría pasar determinado valor a esta variable cuando el usuario presione alguno de los botones «ver» de la izquierda. Pero..

La ruta «index» no es dinámica, es una ruta estática. Por lo que es mejor crear otra ruta aparte que sea dinámica..

Así que borra el código «index_ver = 0» que estábamos pasando en el inicio. Y vamos a ver como hacerlo correctamente!

Rutas estáticas y rutas dinámicas

En este caso sucede que «inicio» es la ruta principal de nuestra aplicación por lo que es una url estática y no podemos convertirla en dinámica o bueno en criollo «no deberíamos» ya que el cliente espera acceder a esta url directamente para encontrarse con la página de inicio.

Una url dinámica en cambio incluye argumentos en su estructura que normalmente ordenan al servidor realizar algún tipo de procesamiento de datos para mostrar un resultado.

Atención!

Y no hay que confundir URL estática o dinámica con Rutas estáticas o dinámicas. Cuando hablamos de url nos referimos a la dirección ingresada en el navegador, como una cadena de caracteres. Pero si nos referimos a rutas lo hacemos a la parte de enrutamiento que responde a esa solicitud desde el lado del servidor!. De nuestras rutas en el controlador!

Así que vamos a nuestro controlador y creamos una ruta dinámica que nos permita pasar el argumento «index» y en ella vamos a cargar el template index.html igualmente como lo hacemos en la ruta «inicio«. Esta ruta debe ser:

  1. Debe admitir solo método GET.
  2. Debe permitir pasar un argumento de número entero.
  3. La función que ejecuta esa ruta debe tener un parámetro para recibir ese argumento.

Fíjate bien como lo hacemos:

@app.route('/ver/<int:index>', methods = ['GET']) 
def ver(index): #Definimos una función llamada Inicio
    Todos = Persona.leer_contacto('id', 'all') 

    return render_template('/index.html', Todos = Todos, index_ver = index) #Retornornamos el template + Todos
  • Estamos definiendo la url «/ver/[un número entero]». Por lo que al acceder a 127.0.0.1:5000/ver/0 tomará el cero como argumento para el parámetro «index».
  • Definimos la función «index» que será la función que ejecute esta ruta, y en ella también creamos el parametro index para recibir dicho argumento.
  • Finalmente debemos pasar igualmente como lo haciamos en «inicio» el diccionario «Todos» con los elementos para que se pueda cargar los elementos en la columna izquierda.
  • Y también pasamos que la variable «index_ver» (que es la que definimos en el bucle for en index.html) será igual a este parámetro pasado en la url.

Ahora te vas a dicha url y voilá:

Ejemplo url dinamica en flask jinja 2

 

Ahora solo nos falta añadir a los botones «Ver» la url que acabamos de crear enviando el valor de «index» como argumento para la variable «index_ver«. Y necesitaremos utilizar «url_for()» el cual básicamente nos permite crear «link’s». Fíjate:

cargar url ver mostrar

Nuestro index.html queda así:

<!DOCTYPE html>
<html lang="es"> <!--Cambiamos a español-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primer App en Flask</title> <!--Modificamos el Título-->
</head>
<body><!--Aquí comienza el cuerpo de nuestro HTML-->

    <h1 style = "text-align:center">Directorio Telefónico - Mi primer aplicación en Flask</h1> <!--Titulo principal centrado-->
    <br>

    <div>    <!--Creamos un div contenedor-->
        <div style="width: 60%; float:left; text-align:center;">    <!--Creamos el div de la izquierda-->
            <h2>Datos completos de la persona</h2>  <!--Titulo-->
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>

                </tr>
                {% for (index, persona) in Todos.items() %}
                {% if index == index_ver %}
                <tr><!--creamos otra fila-->
                    <td>{{persona.nombre}}</td> <!--Aquí se cargarán los datos correspondientes-->
                    <td>{{persona.apellido}}</td>
                    <td>{{persona.apodo}}</td>
                    <td>{{persona.telefono}}</td>
                    <td>{{persona.direccion}}</td>
                </tr>
                {% endif %}
                {% endfor %}
            </table>    <!--Fin de la tabla-->
        </div>  <!--Cierre del div de la izquierda-->

        <div style="width: 40%; float:right; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona.nombre}}, {{persona.apellido}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><a href="{{url_for('ver', index = index)}}"><button name = "ver">Ver</button></a></td><!--Columna que mostrará el botón Ver-->
                    <td><button name = "editar">Editar</button></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><button name = "agregar">Agregar</button></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>
    </div>
</body>
</html>

Y este es el resultado:

 

 

Leeesto! Vamos ahora al botón «editar». Luego prometo hacer un post exclusivo que te servirá de guía para flask + jinja2 donde podrás encontrar tooooda esta información!

Botón «Editar» – Modificar elementos (POST) – UPDATE

Pero lo cierto es que para el botón editar necesitaremos desplegar un formulario que permita ingresar nuevos datos al cliente. Así que lo primero sería crear un formulario para dicha acción, no nos vamos a complicar demasiado, pero estaremos haciendo uso de la solicitud POST ya que estaremos enviando datos al servidor. ¿Recuerdas?

Crear un formulario en FLASK

Para crear un formulario en flask debemos tener un mínimo conocimiento de HTML. Sin duda no es gran cosa, si aún no lo tienes puedes revisar en google y encontrarás mucha información. De forma rápida vamos a centrarnos en la parte de código Python más que en la parte visual.

Por cierto en otros post he utilizado formularios para crear un formulario de contacto en flask.

Lo haremos de la siguiente manera:

  1. Vamos a crearlo puramente en HTML sin librerías. Este form tendrá el método action apuntando a nuestra ruta «/editar» donde modificaremos el elemento.
  2. En el controlador debemos procesar los datos del formulario, por lo que añadiremos la ruta «editar» y en ella debemos añadir un condicional que compruebe si se trata de la solicitud GET o POST.
  3. Por último en nuestro controlador configuramos la edición de el elemento a modificar en la base de datos JSON usando el método que creamos para ello «actualizar_contacto()«

¿Listo?. Vamos!

El código HTML de nuestro formulario y la ruta «editar» en el controlador

Para nuestro formulario simplemente vamos a copiar el código de «index.html» y vamos a modificar la columna izquierda para convertirla en un formulario de edición!. Entonces al momento de presionar el botón «editar» en algún elemento de la lista de la columna derecha nos aparecerá este formulario. Para ello debemos crear otro archivo HTML llamado «editar_contacto.html» y luego crear una ruta:

  1. La ruta «editar» debe permitir método GET y POST.
  2. Además, si se trata de GET debe solo mostrar los datos del formulario.
  3. Pero, si se trata de una solicitud POST debe «obtener» los datos ingresados en el formulario y llamar al método «modificar_contacto()» de nuestro modelo pasando estos atributos a modificar.

Nuestro «editar_contacto.html» ha quedado igual al index.html. Añadimos la ruta «editar» por ahora así:

@app.route('/editar/<int:index>', methods = ['GET', 'POST']) #
def editar(index): #Definimos una función llamada Editar
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'POST':
        pass
    else:
        pass
        

    return render_template('/editar_contacto.html', Todos = Todos, index_ver = index) #Retornornamos el template + Todos
Modifiquemos el botón editar en  «index.html» y «editar_contacto.html» 

boton editar jinja2 url_for

Como ves muy similar al botón «ver«.. Ahora es momento de modificar nuestra plantilla «editar_contacto.html» para incluir un formulario.

Añadir un formulario en plantilla «editar_contacto.html»

El formulario he pensado colocarlo debajo de los datos de la persona que se está intentando modificar. Y ha quedado así:

Formulario1

No me voy a detener demasiado en explicar como funcionan los formularios en html pero si voy a destacar algunas partes del código importantes.

Código de «editar_contacto.html»

<!DOCTYPE html>
<html lang="es"> <!--Cambiamos a español-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primer App en Flask</title> <!--Modificamos el Título-->
</head>
<body><!--Aquí comienza el cuerpo de nuestro HTML-->
    <h1 style = "text-align:center">Directorio Telefónico - Mi primer aplicación en Flask</h1> <!--Titulo principal centrado-->
    <br>
    <div>    <!--Creamos un div contenedor-->
        <div style="width: 60%; float:left; text-align:center;">    <!--Creamos el div de la izquierda-->
            <h2>Datos completos de la persona</h2>  <!--Titulo-->
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>
                </tr>
                {% for (index, persona) in Todos.items() %}
                {% if index == index_ver %}
                <tr><!--creamos otra fila-->
                    <td>{{persona.nombre}}</td> <!--Aquí se cargarán los datos correspondientes-->
                    <td>{{persona.apellido}}</td>
                    <td>{{persona.apodo}}</td>
                    <td>{{persona.telefono}}</td>
                    <td>{{persona.direccion}}</td>
                </tr>
                {% endif %}
                {% endfor %}
            </table>    <!--Fin de la tabla-->
            <h2>Modificar Persona</h2>
            <h4>Base de datos JSON (Index = {{index_ver}} ID ={{Todos[index_ver].id}}) </h4>
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>
                </tr>
                <!-- Inicio del form-->
                <form action = "{{url_for('editar', index = index_ver)}}" method = "post">
                <tr><!--creamos otra fila-->
                      <!--Pasamos el id oculto -->
                    <input type = "hidden" name = "id" value = {{Todos[index_ver].id}}></input> 
                    <td><input type = "name" name = "Nombre" value = "{{Todos[index_ver].nombre}}" style = "max-width: 100px;"></input></td> <!--Aquí se cargarán los datos correspondientes-->
                    <td><input type = "name" name = "Apellido" value = "{{Todos[index_ver].apellido}}" style = "max-width: 100px;"></input></td>
                    <td><input type = "name" name = "Apodo" value = "{{Todos[index_ver].apodo}}" style = "max-width: 100px;"></input></td>
                    <td><input type = "tel" name = "Telefono" value = "{{Todos[index_ver].telefono}}" style = "max-width: 100px;"></input></td>
                    <td><input type = "name" name = "Direccion" value = "{{Todos[index_ver].direccion}}" style = "max-width: 100px;"></input></td>
                </tr>
            
            </table><!--Fin de la tabla-->
            <br>
            <a href="#"><button type="submit">Modificar</button></a>   
        </form><!-- Fin del formulario-->
        
        </div>  <!--Cierre del div de la izquierda-->
        <div style="width: 40%; float:right; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona.nombre}}, {{persona.apellido}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><a href="{{url_for('ver', index = index)}}"><button name = "ver">Ver</button></a></td><!--Columna que mostrará el botón Ver-->
                    <td><a href="{{url_for('editar', index = index)}}"><button name = "editar">Editar</button></a></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><button name = "agregar">Agregar</button></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>
    </div>
</body>
</html>

 

Además de los campos tradicionales quería resaltar que hemos añadido el valor por defecto que sea igual al que ya se encuentra almacenado en la base de datos, entonces luego al obtener los datos del formulario en el controlador el cambio solo se producirá en el elemento modificado y los demás se guardar igual a como estaban. Y me refiero al elemento «value» que es aquel que el formulario asume por defecto!

Como ves el «action» de nuestro form conduce a la función de la ruta «editar» + el «index_ver» por lo que ahora debemos procesar los datos que el usuario ingrese desde el controlador en la ruta «editar» dentro del condicional POST.

Pero para comprobar si funciona simplemente sin editar nada puedes presionar el botón «modificar» y en la terminal deberás obtener el resultado de la solicitud POST!

Procesar los datos sería el paso 3 como te detalle más arriba y lo hacemos así:

@app.route('/editar/<int:index>', methods = ['GET', 'POST']) #
def editar(index): #Definimos una función llamada Editar
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'POST': #Si el método es POST
        #Obtenemos los datos del formulario y los almacenamos en variables
        id = int(request.form['id']) #Obtenemos "id" y lo convertimos en entero
        Nombre = request.form['Nombre']
        Apellido = request.form['Apellido']
        Apodo = request.form['Apodo']
        Telefono = request.form['Telefono']
        Direccion = request.form['Direccion']
        #Ejecutar el método actualizar_contacto() usando el "id"
        Persona.actualizar_contacto(id, 'nombre', Nombre)
        Persona.actualizar_contacto(id, 'apellido', Apellido)
        Persona.actualizar_contacto(id, 'apodo', Apodo)
        Persona.actualizar_contacto(id, 'telefono', Telefono)
        Persona.actualizar_contacto(id, 'direccion', Direccion)

        
    else:
        pass
        

    return render_template('/editar_contacto.html', Todos = Todos, index_ver = index) #Retornornamos el template + Todos
  1. Hemos creado la función editar() y le hemos pasado como parámetro «index» que recibirá el número de index del elemento que queremos modificar.
  2. Seguido se comprobará mediante un condicional si se trata de una solicitud POST y de ser así se ejecutará el bloque de código dentro del condicional.
  3. Dicho bloque de código obtiene los datos del formulario HTML que creamos para editar elementos en la base de datos, entre ellos el «id» que lo estamos pasando como dato oculto a la vista del usuario. Más que oculto sería decir que no se lo estamos pidiendo, sino que lo obtenemos automáticamente. Estos datos obtenidos del formulario son almacenados dentro de variables que tienen el mismo nombre que el atributo pero comienzan con mayúsculas.
  4. Finalmente llamamos al método actualizar_contacto() que se encargará como definimos en el modelo de almacenar los cambios en la base de datos JSON. [En el modelo hubiéramos podido programar el método para recibir todos los atributos y valores a la vez, mala mía. Tu puedes corregirlo para evitar llamar una vez al método por cada atributo y valor a modificar.]
  5. Como ves en caso de no tratarse de una solicitud POST simplemente escapa al condicional y carga el sitio normalmente retornando el template y las variables Todos, index.

 

Botón «Agregar» – Añadir elementos (POST) – CREATE

Para crear nuevos elementos simplemente podemos repetir los pasos anteriores pero creando una plantilla HTML nueva y llamando al método POST en una ruta CREATE:

Primer paso, añadimos una url al botón «Agregar» en todos los templates, no olvides en el «index.html«:

Botón agregar

Segundo paso creamos un archivo html llamado «agregar_contacto.html» dentro de la carpeta «templates» y creamos la ruta en el controlador llamada «agregar» donde returne un render_template(«agregar_contacto.html, Todos = Todos). Vamos que lo venimos haciendo como 3 veces!

Y dentro de ese html «agregar_contacto.html» simplemente copias el código mismo del mismo «editar_contacto.html» y procedes a modificarlo a tu gusto.

Eliminamos la primer tabla donde mostrábamos los datos completos de un contacto. Modificamos el action del form apuntando a «agregar» en vez de a «editar» y modificamos el nombre del botón modificar. Además debemos cambiar los valores «default» (values) de nuestro formulario por lo que el cliente deberá ingresar:

agregar_form

Si dejamos valores en «value» el cliente tendrá que borrarlos para escribir. En cambio podemos usar «placeholder» lo que permitirá que al colocar el cursor el cliente o usuario no tenga que borrar ningún valor por defecto, simplemente servirá como dato orientativo de lo que debe colocar en el formulario y se verá así:

agregar_persona

 

Nuestro código de «agregar_contacto.html» quedaría:

<!DOCTYPE html>
<html lang="es"> <!--Cambiamos a español-->
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi primer App en Flask</title> <!--Modificamos el Título-->
</head>
<body><!--Aquí comienza el cuerpo de nuestro HTML-->
    <h1 style = "text-align:center">Directorio Telefónico - Mi primer aplicación en Flask</h1> <!--Titulo principal centrado-->
    <br>
    <div>    <!--Creamos un div contenedor-->
        <div style="width: 60%; float:left; text-align:center;">    <!--Creamos el div de la izquierda-->

            <h2>Agregar Persona</h2>
            <table border = "1" style = "width: 100%;"> <!--Creamos la tabla con borde-->
                <tr><!--Creamos una fila-->
                    <td>Nombre</td> <!--Dentro de la fila las columnas-->
                    <td>Apellido</td>
                    <td>Apodo</td>
                    <td>Teléfono</td>
                    <td>Dirección</td>
                </tr>
                <!-- Inicio del form-->
                <form action = "{{url_for('agregar')}}" method = "post">
                <tr><!--creamos otra fila-->
                    <td><input type = "name" name = "Nombre" placeholder = "Nombre" style = "max-width: 100px;"></input></td> <!--Aquí se cargarán los datos correspondientes-->
                    <td><input type = "name" name = "Apellido" placeholder = "Apellido" style = "max-width: 100px;"></input></td>
                    <td><input type = "name" name = "Apodo" placeholder = "Apodo" style = "max-width: 100px;"></input></td>
                    <td><input type = "tel" name = "Telefono" placeholder = "Teléfono" style = "max-width: 100px;"></input></td>
                    <td><input type = "name" name = "Direccion" placeholder = "Dirección" style = "max-width: 100px;"></input></td>
                </tr>
            
            </table><!--Fin de la tabla-->
            <br>
            <a href="#"><button type="submit">Agregar</button></a>   
        </form><!-- Fin del formulario-->

        </div>  <!--Cierre del div de la izquierda-->
        <div style="width: 40%; float:right; text-align:center;"> <!--Div de la derecha-->
            <h2>Personas</h2> <!--Titulo-->
            <table border = "1" style = "width: 100%;"><!--Tabla de la derecha-->
                    {% for (index, persona) in Todos.items() %}
                    <tr><!--Fila-->
                    <td>{{persona.nombre}}, {{persona.apellido}}</td><!--Columna que mostrará el nombre y apellido-->
                    <td><a href="{{url_for('ver', index = index)}}"><button name = "ver">Ver</button></a></td><!--Columna que mostrará el botón Ver-->
                    <td><a href="{{url_for('editar', index = index)}}"><button name = "editar">Editar</button></a></td><!--Columna que mostrará el botón Editar-->
                    <td><button name = "eliminar">Eliminar</button></td><!--Columna que mostrará el botón Eliminar-->
                    </tr>
                    {% endfor %}
                <tr>
                    <td><a href="{{url_for('agregar')}}"><button name = "agregar">Agregar</button></a></td><!--Columna que mostrará el botón Agregar-->
                </tr>
            </table>
        </div>
    </div>
</body>
</html>

Y en nuestro controlador.py realizamos la ruta «agregar» donde recolectamos los datos del formulario, y creamos una instancia de la clase Persona para luego llamar al método Create de nuestro modelo.py:

@app.route('/agregar', methods = ['GET','POST'])
def agregar():
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'POST':
        #Obtenemos los datos del formulario:
        Nombre = request.form['Nombre']
        Apellido = request.form['Apellido']
        Apodo = request.form['Apodo']
        Telefono = request.form['Telefono']
        Direccion = request.form['Direccion']
        #Creamos una instancia de la clase persona usando estos datos almacenados:
        Nuevo_contacto = Persona (Nombre, Apellido, Apodo, Telefono, Direccion)
        Nuevo_contacto.crear_contacto()
        return redirect('agregar') #RECARGAMOS EL SITIO PARA MOSTRAR EL NUEVO CONTACTO
    else:
        pass

    return render_template('/agregar_contacto.html', Todos = Todos) #Retornornamos el template + Todos

Además añadimos un return «redirect» para re-dirigirnos nuevamente a «agregar«, básicamente solo estamos recargando la página para que en nuestra columna de la izquierda se cargue el nuevo elemento que añadimos. Ya que al recargar la página se realiza la solicitud GET y por ende se vuelve a ejecutar el bucle For que utilizamos para dicha finalidad!. Pura genialidad!

Código de nuestro controlador.py completo:

from flask import Flask, redirect, request, render_template #Importamos clase Flask, objeto request de flask (librería)
app = Flask(__name__) #Creamos una app instanciando la clase Flask (automáticamente el nombre de la app)
from models import Persona


#Rutas - (argumentos: Url) - Función

@app.route('/', methods = ['GET']) #Decoramos con método de app que es una instancia de la clase Flask y argumentamos "slash"
def inicio(): #Definimos una función llamada Inicio
    #Llamamos al método para listar personas y lo almacenamos en "Todos"
    Todos = Persona.leer_contacto('id', 'all') 
    return render_template('/index.html', Todos = Todos, index_ver = 0) #Retornornamos el template + Todos

@app.route('/ver/<int:index>', methods = ['GET']) 
def ver(index): #Definimos una función llamada Ver
    Todos = Persona.leer_contacto('id', 'all') 

    return render_template('/index.html', Todos = Todos, index_ver = index) #Retornornamos el template + Todos

@app.route('/editar/<int:index>', methods = ['GET', 'POST']) #
def editar(index): #Definimos una función llamada Editar
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'POST': #Si el método es POST
        #Obtenemos los datos del formulario y los almacenamos en variables
        id = int(request.form['id']) #Obtenemos "id" y lo convertimos en entero
        Nombre = request.form['Nombre']
        Apellido = request.form['Apellido']
        Apodo = request.form['Apodo']
        Telefono = request.form['Telefono']
        Direccion = request.form['Direccion']
        #Ejecutar el método actualizar_contacto() usando el "id"
        Persona.actualizar_contacto(id, 'nombre', Nombre)
        Persona.actualizar_contacto(id, 'apellido', Apellido)
        Persona.actualizar_contacto(id, 'apodo', Apodo)
        Persona.actualizar_contacto(id, 'telefono', Telefono)
        Persona.actualizar_contacto(id, 'direccion', Direccion)

        
    else:
        pass
        

    return render_template('/editar_contacto.html', Todos = Todos, index_ver = index) #Retornornamos el template + Todos

@app.route('/agregar', methods = ['GET','POST'])
def agregar():
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'POST':
        #Obtenemos los datos del formulario:
        Nombre = request.form['Nombre']
        Apellido = request.form['Apellido']
        Apodo = request.form['Apodo']
        Telefono = request.form['Telefono']
        Direccion = request.form['Direccion']
        #Creamos una instancia de la clase persona usando estos datos almacenados:
        Nuevo_contacto = Persona (Nombre, Apellido, Apodo, Telefono, Direccion)
        Nuevo_contacto.crear_contacto()
        return redirect('agregar') #RECARGAMOS EL SITIO PARA MOSTRAR EL NUEVO CONTACTO
    else:
        pass

    return render_template('/agregar_contacto.html', Todos = Todos) #Retornornamos el template + Todos

@app.route('/agradecimiento', methods = ['GET']) #Decoramos con método routes la próxima función arguementando la url "/agradecimiento"
def agradecer(): #Definimos una función llamada agradecer
    return 'Gracias pythones.net!' #Retorno de la función

#Iniciar app

if __name__ == '__main__': #Condicional de que si la aplicación ejecutada se coincide al nombre de la aplicación
    app.run('127.0.0.1', 5000, debug=True) #Método que inicia la app con la dirección, puertos y modo de argumentos

Resultado:

Finalmente nos estaría faltando.. El botón para destruir!. El botón de «Eliminar» y el más sencillo de construir!

Botón «Eliminar» – Eliminar elementos (GET) – DELETE

En este caso como método utilizaremos GET (luego explicaré porque), pasando el número de id del elemento a eliminar:

eliminar

 

Finalmente solo nos bastará llamar al método eliminar_contacto() desde el controlador estableciendo un condicional en caso de una solicitud GET y pasando el id correspondiente en la ruta y función:

@app.route('/eliminar/<int:id>', methods = ['GET']) #USAR GET
def eliminar(id):
    Todos = Persona.leer_contacto('id', 'all')
    if request.method == 'GET': #Si el método es GET
        Persona.eliminar_contacto(id)
        return redirect ('/')
    else:
        pass

    return render_template('/index.html', Todos = Todos) #Retornornamos el template + Todos

Resultado:

 

¿Por qué usé solo GET y POST para explicar CRUD?

Como recordarás te había dicho antes que se suelen utilizar 4 tipos de solicitudes «PUT, GET, POST, DELETE». Pero en este caso hemos usado solo GET y POST porque PUT y DELETE deben ser llamadas desde una solicitud AJAX y no pueden ser utilizadas siendo llamadas como solicitudes HTTP ni desde un formulario.

 

Bien esto ha sido todo en esta lección. Hemos aprendido a crear una aplicación sencilla aprendiendo y utilizando el concepto CRUD a la vez que aprendemos a utilizar FLASK. Aclaro nuevamente que este post está muy lejos de una aplicación profesional; es solo con motivos explicativos y prácticos donde evito sobrecargar demasiado con otros conceptos, librerías, etc para hacerlo más ameno al aprendiz de desarrollo de aplicaciones con FLASK.

Como siguiente entrada vamos a trabajar con bases de datos MySQL e intentaré integrar aquellos antiguos post teóricos de diseño de bases de datos relacionales. Espero que esta serie de post hallan sido de su agrado, nos vemos en la siguiente entrada. Abrazo!


 

 

Continúa leyendo!
Entrada anterior! Resumen de Flask – Teoría + Práctica + Ejemplos
Compartir es agradecer! :)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.