Guía 23

Guía 23

DAWM / Proyecto05

Objetivo general

Desarrollar una aplicación backend robusta y escalable utilizando Django que integre una interfaz de administrador intuitiva para la gestión eficiente de datos y funcionalidades junto con un REST API completo que facilite la comunicación con las aplicaciones cliente de tal forma que garantice la seguridad, el rendimiento y la extensibilidad del sistema.

Actividades previas

Ambiente de desarrollo

  1. Desde la línea de comandos

    • Cree y habilite el ambiente de desarrollo, con:
     python -m venv environment
     environment\Scripts\activate
    

Repositorio local/remoto + librerías

  1. Desde la línea de comandos

    • Clone localmente y acceda a la carpeta backend.
    • Instale las librerías de requirements.txt, con:
     pip install -r requirements.txt
    

SDK Firebase Admin: Clave privada

  1. Acceda a la consola de Firebase
  2. Ingrese al proyecto landing
    • Acceda a la Configuración de proyecto.
    • Genere y descargue una clave privada JSON.
  3. Cree la carpeta keys en el proyecto.
  4. Renombre el archivo como landing-key.json y guarde el archivo en la carpeta keys.

Editor y WSGI

  1. Abra el proyecto con VSCode, con:

     code .
    
  2. Levante el servidor, con:

     python manage.py runserver
    

Actividades en clases

Plantilla para datos

  1. Descargue y descomprima el archivo main_content_data_django.zip
  2. Reemplace el archivo descargado por templates/main/content/data.html.
  3. (STOP 1) Revise los cambios en el navegador en el URL:

Vistas y plantillas: Renderización de constantes

  1. Edite el archivo main/views.py, con:

    • Cree el objeto data y renderice en la vista index
     ...
    
     def index(request):
            
         # Objeto con los datos a renderizar
         data = {
             'title': 'Landing - Dashboard',
         }
    
    
         # Renderización en la plantilla
         return render(request, 'main/index.html', data)
    
  2. Modifique el archivo templates/main/content/data.html, con:

    • Renderice la variable title
     ...
    
     <!-- START - title -->
         {{ title }}
     <!-- END - title -->
    
     ...
    
  3. (STOP 2) Revise los cambios en el navegador en el URL:

Vistas y plantillas: Renderización de variables

  1. Edite el archivo main/views.py, con:

    • Importe requests y json.
    • Arme el endpoint con la URL del proyecto y la ruta de la aplicación.
    • Realice una petición al REST API al endpoint.
     ...
    
     # Importe requests y json
     import requests
     import json
    
     def index(request):
            
         # Arme el endpoint del REST API
         current_url = request.build_absolute_uri()
         url = current_url + '/api/v1/landing'
    
         # Petición al REST API
         response_http = requests.get(url)
         response_dict = json.loads(response_http.content)
    
         print("Endpoint ", url)
         print("Response ", response_dict)
    
         # Respuestas totales
         total_responses = len(response_dict.keys())
    
         # Objeto con los datos a renderizar
         data = {
             'title': 'Landing - Dashboard',
             'total_responses': total_responses,
         }
    
         # Renderización en la plantilla
         return render(request, 'main/index.html', data)
    
  2. Modifique el archivo templates/main/content/data.html, con:

    • Renderice la variable total_responses en los bloques total_responses y total_responses_table
     ...
    
     <!-- START - total_responses -->
         {{ total_responses }}
     <!-- END - total_responses -->
    
     ...
    
     <!-- START - total_responses_table -->
         {{ total_responses }}
     <!-- END - total_responses_table -->
     respuestas
    
  3. (STOP 3) Revise los cambios:

    • En la terminal

Vistas y plantillas: Renderización de arreglos

  1. Edite el archivo main/views.py, con:

    • Extraiga los valores de la respuesta
     ...
    
     # Importe requests y json
     import requests
     import json
    
     def index(request):
            
         ...
    
         # Respuestas totales
         ...
    
         # Valores de la respuesta
         responses = response_dict.values()
    
         # Objeto con los datos a renderizar
         data = {
             'title': 'Landing - Dashboard',
             'total_responses': total_responses,
             'responses': responses
         }
    
         # Renderización en la plantilla
         return render(request, 'main/index.html', data)
    
  2. Modifique el archivo templates/main/content/data.html, con:

    • Itere el arreglo responses en la variable row.
    • Renderice los valores row.email y row.saved.
     ...
    
     <!-- START - responses -->
     {% for row in responses %}
     <tr class="text-gray-700 dark:text-gray-400">
         <td class="px-4 py-3 text-sm">
             <!-- START - row.email -->
             {{ row.email }}
             <!-- END - row.email -->
         </td>
         <td class="px-4 py-3 text-sm">
             <!-- START - row.saved -->
             {{ row.saved }}
             <!-- END - row.saved -->
         </td>
     </tr>
     {% endfor %}
     <!-- END - responses -->
    
     ...
    
  3. (STOP 4) Revise los cambios:

Javascript: Requerimiento asíncrono

  1. Edite el archivo static/js/charts-pie.js, con:

    • Agregue la función countCommentsByHour que procesa el JSON de respuesta.
     ...
        
     const pieCtx = ...
     window.myPie = ...
    
     // Función para procesar el JSON
     countCommentsByHour = (data) => {
    
       // Inicializar contadores por rango de horas
       const labels = ["0 a.m. - 8 a.m.", "8 a.m. - 16 p.m.", "16 p.m. - 0 a.m."];
       const counts = [0, 0, 0];
    
       Object.values(data).forEach(record => {
    
           const savedTime = record.saved;
           if (!savedTime) {
               return;
           }
    
           // Convertir a formato de hora AM/PM
           const formattedTime = savedTime.replace('a. m.', 'AM').replace('p. m.', 'PM');
              
           // Crear objeto Date con la cadena de tiempo
           const dt = new Date(Date.parse(formattedTime.replace(/(\d{2}\/\d{2}\/\d{4}), (\d{2}):(\d{2}):(\d{2}) (AM|PM)/, '$1 $2:$3:$4 $5')));
           const hour = dt.getHours();
    
           // Clasificar en el rango correspondiente
           if (hour >= 0 && hour < 8) {
               counts[0]++;
           } else if (hour >= 8 && hour < 16) {
               counts[1]++;
           } else {
               counts[2]++;
           }
       });
    
       return { labels, counts };
     }
    
    • Agregue la función update con la petición asincrónica al REST API y actualiza el gráfico.
     ...
    
     countCommentsByHour = { ... }
    
     update = () => {
       fetch('/api/v1/landing')
         .then(response => response.json())
         .then(data => {
    
           let { labels, counts } = countCommentsByHour(data)
    
           // Reset data
           window.myPie.data.labels = [];
           window.myPie.data.datasets[0].data = [];
    
           // New data
           window.myPie.data.labels = [...labels]
           window.myPie.data.datasets[0].data = [...counts]
    
           window.myPie.update();
    
         })
         .catch(error => console.error('Error:', error));
     }
    
     update();
    
  2. (STOP 5) Revise los cambios:

Versionamiento local y remoto

  1. En la línea de comandos

    • Genere el archivo requirements.txt con la lista de paquetes utilizados, con:
     pip freeze > requirements.txt
    
    • Desactive el ambiente de desarrollo, con:
     deactivate
    
  2. Versione local y remotamente.

Documentación

Fundamental

Términos

SSR, endpoint, etiquetas integradas

Referencias