DEV Community

Cover image for Desarrollo de Ecommerce con Django (parte 4)
Gabriel Villacis
Gabriel Villacis

Posted on

Desarrollo de Ecommerce con Django (parte 4)

Este tutorial cubre los siguientes puntos:

  • Layout de la web.
  • Configuración de archivos estáticos.
  • Herencia de plantillas.

1. Reestructurar el layout de la plantilla principal

Vamos a estructurar el layout para que tenga una zona de header, nav, main y footer.

Usemos el siguiente código que está basado en los ejemplos de bootstrap 5:

{% load static %}

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EELA Ecommerce</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <link rel="shortcut icon" href="{% static 'img/icon.png' %}" type="image/x-icon">
</head>

</head>
<body>
    <div class="container-fluid">

        <!-- Header -->
        <header class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between py-3 mb-4 border-bottom">
            <a href="{% url 'home' %}" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
              <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg>
            </a>

            <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
              <li><a href="#" class="nav-link px-2 link-secondary">Home</a></li>
              <li><a href="#" class="nav-link px-2 link-dark">Quiénes somos</a></li>
              <li><a href="#" class="nav-link px-2 link-dark">FAQs</a></li>              
            </ul>

            <div class="col-md-3 text-end">
              {% if user.is_authenticated %}
                <a href="#" class="nav-link link-body-emphasis px-2">Bienvenido, {{user.username}}</a>
                <a href="{% url 'logout' %}" class="nav-link link-body-emphasis px-2">Logout</a>                
              {% else %}
                <a href="{% url 'signin' %}" class="btn btn-outline-primary me-2">Login</a>
                <a href="{% url 'signup' %}" class="btn btn-primary">Sign-up</a>
              {% endif %}
            </div>
        </header>

        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg bg-body-tertiary">
            <div class="container-fluid">
              <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                      Categorías
                    </a>
                    <ul class="dropdown-menu">
                      <li><a class="dropdown-item" href="{% url 'home' %}">Todas las categorías</a></li>                      
                    </ul>
                  </li>
                </ul>
                <form class="d-flex" role="search">
                  <input class="form-control me-2" type="search" placeholder="Producto..." aria-label="Search">
                  <button class="btn btn-outline-primary" type="submit">Buscar</button>
                </form>
              </div>
            </div>
        </nav>

        <!-- Main -->
        <main class="container">

            <h1 class="text-center">Catálogo de Productos</h1>
            <div class="my-3 row row-cols-1 row-cols-md-3 g-4">
                {% for producto in productos %}
                <div class="col">
                    <div class="card h-100">
                        <img src="{{producto.imagen.url}}" alt="...">
                        <div class="card-body">
                            <h5 class="card-title">{{producto.nombre}}</h5>
                            <p class="card-text">{{producto.descripcion}}</p>
                        </div>
                        <div class="card-footer">
                            <small class="text-body-secondary">${{producto.precio}}</small>
                        </div>
                    </div>
                </div>
                {% endfor %}             
            </div>

        </main>

        <!-- Footer-->
        <footer class="py-5 bg-primary mb-2">
            <div class="container"><p class="m-0 text-center text-white">Copyright &copy; Escuela de Emprendimiento (EELA) 2024</p></div>
        </footer>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>`
Enter fullscreen mode Exit fullscreen mode

Este layout está incorporando el uso de archivos estáticos, por lo cual debemos configurarlo en el proyecto.

  • Creemos la carpeta static en el directorio del proyecto.
  • Vamos a ir a settings.py para registrar la variable STATICFILES_DIRS de la siguiente manera:

STATICFILES_DIRS = (BASE_DIR / 'static',)

Para probar agreguemos una subcarpeta img donde guardemos imágenes como el favicon de la web.

Cuando necesitemos usar los archivos estáticos en una plantilla debemos incluir la directiva {% load static %} al inicio de la plantilla y para un archivo específico usamos {% static 'path_del_archivo' %}.

*2. Herencia de plantillas *
Para realizar la herencia de plantillas vamos a incorporar en la plantilla base la definición de un bloque. Por ejemplo:

En la plantilla index.html declaramos:

<main class="my-5">
  {% block contenido %}
  {% endblock %}
</main>
Enter fullscreen mode Exit fullscreen mode

Y creamos una nueva plantilla catalog.html la cual extenderá index.html y definirá el bloque contenido:

{% extends 'index.html' %}

{% block contenido %}

  <!-- Aquí va el código para presentar el detalle del catálogo -->

{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)