En este capítulo desarrollaremos parte de la aplicación Tienda. Aquí mostraremos los diferentes productos que pretendemos vender en ella. A través de un menú de pestañas mostraremos los diferentes juegos que tenemos para las diferentes plataformas. Luego mostraremos los juegos de cada plataforma a través de tarjetas ("cards") de bootstrap5, cuatro por cada fila. Quedará algo similar a esto:
La creación de la aplicación es muy similar al resto que hemos visto hasta ahora:
1.- Creamos la nueva aplicación que gestionará la tienda.
$ python manage.py startapp Tienda
2.- Una vez creada la registramos:
PracticaDjango/PracticaDjango/settings.py
...
INSTALLED_APPS = [
# Nuestras aplicaciones
'Proyecto_web_app.apps.ProyectoWebAppConfig',
'Servicios.apps.ServiciosConfig',
'Blog.apps.BlogConfig',
'Contacto.apps.ContactoConfig',
'Tienda.apps.TiendaConfig',
# Aplicaciones de terceros
'django_bootstrap5',
# Mapa del Sitio
'django.contrib.sites', # add sites to installed_apps
'django.contrib.sitemaps', # add Django sitemaps to installed app
# PostgreSQL
'django.contrib.postgres',
# Aplicaciones por defecto
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
...PracticaDjango/PracticaDjango/urls.py:
from django.contrib import admin
from django.urls import path, include
# Para registrar los archivos de las imagenes y poder verlas
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('Proyecto_web_app.urls')),
path('servicios/', include('Servicios.urls')),
path('blog/', include('Blog.urls')),
path('contacto/', include('Contacto.urls')),
path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
path('tienda/', include('Tienda.urls')),
]
urlpatterns+=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)y luego en archivo que gestiona las urls de la tienda. Entra en el directorio de la aplicación Tienda, crea el archivo urls.py y añade el siguiente código:PracticaDjango/Tienda/urls.py:
from django.urls import path
# load views of these applications.
from . import views
app_name = 'Tienda'
urlpatterns = [
path('', views.tienda, name='tienda'),
]Más tarde crearemos la vista y la plantilla a renderizar. Pero antes vamos a preparar otras cosas.
Creación de modelos para el catálogo de productos.
PracticaDjango/Tienda/models.py:
from django.db import models
# Create your models here.
# Creamos dos modelos para la categoría del producto (tipo de consola)
# y para el producto (el juego en si).
class CategoriaProducto(models.Model):
'''Registrará las diferentes consolas para las que vendemos juegos'''
nombre = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
class Meta:
ordering = ["nombre"]
indexes = [
models.Index(fields=["nombre"]),
]
verbose_name = "categoriaProducto"
verbose_name_plural = "categoriasProductos"
def __str__(self):
return self.nombre
class Producto(models.Model):
"""Registra los propios juegos en si."""
nombre = models.CharField(max_length=200)
slug = models.SlugField(max_length=200)
categoria = models.ForeignKey(
CategoriaProducto, on_delete=models.CASCADE, related_name="categoria_productos"
)
descripcion = models.CharField(blank=True)
precio = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.BooleanField(default=True)
# hay que tener instalado la libreria pillow para poder subir imagenes
imagen = models.ImageField(upload_to="Tienda", blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ["nombre"]
indexes = [
models.Index(fields=["id", "slug"]),
models.Index(fields=["nombre"]),
models.Index(fields=["-created"]),
]
verbose_name = "producto"
verbose_name_plural = "productos"
def __str__(self):
return self.nombre
Registrando los modelos en el panel de administración.
PracticaDjango/Tienda/admin.py:
from django.contrib import admin
from .models import *
# Register your models here.
class CategoriaProductoAdmin(admin.ModelAdmin):
list_display = ["nombre", "slug"]
prepopulated_fields = {"slug": ("nombre",)}
class ProductoAdmin(admin.ModelAdmin):
list_display = ["nombre", "slug", "precio", "stock", "created", "updated"]
list_filter = ["stock", "created", "updated"]
list_editable = ["precio", "stock"]
prepopulated_fields = {"slug": ("nombre",)}
# Registramos ambas tablas y clases
admin.site.register(CategoriaProducto, CategoriaProductoAdmin)
admin.site.register(Producto, ProductoAdmin) Construyendo las vistas.
PracticaDjango/Tienda/views.py:
from django.shortcuts import render
# Como trabajamos con productos vamos a importarlos
from Tienda.models import Producto
# Create your views here.
def tienda(request):
productos = Producto.objects.filter(stock=True)
# carga en la variable productos todos los juegos que hayamos introducido a través
# del panel de administración de Django.
contexto = {
"productos": productos
}
return render(request, "Tienda/tienda.html", contexto)
PracticaDjango/Tienda/templates/Tienda/tienda.html
<!--Cargamos la plantilla base-->
{% extends "Proyecto_web_app/base.html" %}
<!-- Establecemos el titulo de la página -->
{% block title %}Tienda{% endblock %}
<!-- Definimos su contenido -->
{% block content %}
<h1 class="text-center">Elige tu Consola.</h1>
<div class="container">
<div class="bg-dark">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" id="ps4-tab" data-bs-toggle="tab" href="#ps4" role="tab" aria-controls="ps4"
aria-selected="true">PS4</a>
</li>
<li class="nav-item">
<a class="nav-link" id="ps5-tab" data-bs-toggle="tab" href="#ps5" role="tab" aria-controls="ps5"
aria-selected="false">PS5</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xbox-tab" data-bs-toggle="tab" href="#xbox" role="tab" aria-controls="xbox"
aria-selected="false">Xbox</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xbox-tab" data-bs-toggle="tab" href="#nintendo" role="tab" aria-controls="xbox"
aria-selected="false">Nintendo</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane fade show active" id="ps4" role="tabpanel" aria-labelledby="ps4-tab">
<h3>Juegos PS4</h3>
<div class="row g-4">
{% for producto in productos %}
{% if producto.categoria_id == 1 %}
<div class="col-md-3">
<div class="card h-100" style="width:200px">
<img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{producto.nombre}}</h4>
<p class="card-text">{{producto.precio}} €</p>
<a href="#" class="btn btn-primary">See Profile</a>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
<div class="tab-pane fade" id="ps5" role="tabpanel" aria-labelledby="ps5-tab">
<h3>Juegos PS5</h3>
<!-- Contenido para juegos PS5 -->
<div class="row g-4">
{% for producto in productos %}
{% if producto.categoria_id == 2 %}
<div class="col-md-3">
<div class="card h-100" style="width:200px">
<img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{producto.nombre}}</h4>
<p class="card-text">{{producto.precio}} €</p>
<a href="#" class="btn btn-primary">See Profile</a>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
<div class="tab-pane fade" id="xbox" role="tabpanel" aria-labelledby="xbox-tab">
<h3>Juegos Xbox</h3>
<!-- Contenido para juegos Xbox -->
<div class="row g-4">
{% for producto in productos %}
{% if producto.categoria_id == 3 %}
<div class="col-md-3">
<div class="card h-100" style="width:200px">
<img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{producto.nombre}}</h4>
<p class="card-text">{{producto.precio}} €</p>
<a href="#" class="btn btn-primary">See Profile</a>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
<div class="tab-pane fade" id="nintendo" role="tabpanel" aria-labelledby="xbox-tab">
<h3>Juegos Nintendo</h3>
<!-- Contenido para juegos Nintendo -->
<div class="row g-4">
{% for producto in productos %}
{% if producto.categoria_id == 4 %}
<div class="col-md-3">
<div class="card h-100" style="width:200px">
<img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{producto.nombre}}</h4>
<p class="card-text">{{producto.precio}} €</p>
<a href="#" class="btn btn-primary">See Profile</a>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}Esta plantilla de Django es utilizada para renderizar una página web que muestra diferentes juegos de consolas divididos en pestañas. A continuación, explicaré cada parte de la plantilla en detalle:
Carga de la plantilla base:
/PracticaDjango/Tienda/templates/Tienda/tienda.html
{% extends "Proyecto_web_app/base.html" %}
/PracticaDjango/Tienda/templates/Tienda/tienda.html
{% block title %}Tienda{% endblock %}
/PracticaDjango/Tienda/templates/Tienda/tienda.html
{% block content %}
...
{% endblock %}
/PracticaDjango/Tienda/templates/Tienda/tienda.html
<h1 class="text-center">Elige tu Consola.</h1>
/PracticaDjango/Tienda/templates/Tienda/tienda.html
<div class="container">
<div class="bg-dark">
<ul class="nav nav-tabs">
...
</ul>
</div>
/PracticaDjango/Tienda/templates/Tienda/tienda.html
<div class="tab-content">
<div class="tab-pane fade show active" id="ps4" role="tabpanel" aria-labelledby="ps4-tab">
...
</div>
<div class="tab-pane fade" id="ps5" role="tabpanel" aria-labelledby="ps5-tab">
...
</div>
<div class="tab-pane fade" id="xbox" role="tabpanel" aria-labelledby="xbox-tab">
...
</div>
<div class="tab-pane fade" id="nintendo" role="tabpanel" aria-labelledby="xbox-tab">
...
</div>
</div>
<div class="tab-pane fade"> representa el contenido de una pestaña específica. El atributo id identifica el contenido de cada pestaña, y el atributo role especifica el papel de la pestaña./PracticaDjango/Tienda/templates/Tienda/tienda.html
{% for producto in productos %}
{% if producto.categoria_id == 1 %}
...
{% endif %}
{% endfor %}
for de Django que itera sobre una lista de productos. Dentro del bucle, se comprueba si el producto pertenece a una categoría específica (identificada por el atributo categoria_id). En este ejemplo, se muestra el código 1 ya que corresponde a la categoria_id de PS4. La 2 es la de PS5, la 3 es XBOX y la 4 a Nintendo./PracticaDjango/Tienda/templates/Tienda/tienda.html
<div class="col-md-3">
<div class="card h-100" style="width:200px">
<img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image">
<div class="card-body">
<h4 class="card-title">{{producto.nombre}}</h4>
<p class="card-text">{{producto.precio}} €</p>
<a href="#" class="btn btn-primary">See Profile</a>
</div>
</div>
</div>
producto.imagen.url), el nombre del juego (producto.nombre), el precio (producto.precio) y un botón de "See Profile". Se utiliza la sintaxis de plantillas de Django ({{ ... }}) para incrustar los valores de los atributos de los productos dentro de la plantilla./PracticaDjango/Tienda/templates/Tienda/tienda.html
<div class="row g-4">
...
</div>La línea <div class="row g-4"> es una clase de Bootstrap 5 que se utiliza para crear una fila (row) en un sistema de grillas (grid). A continuación se explica su significado:
<div>: Es un elemento HTML de división utilizado para agrupar contenido.class="row": Es una clase de Bootstrap que define una fila en el sistema de grillas. Las filas son utilizadas para organizar el contenido en columnas dentro de un contenedor.g-4: Es una clase de Bootstrap que agrega un espacio (g) entre las columnas dentro de la fila. El número4indica el tamaño del espacio en píxeles. En este caso, se establece un espacio de 4 píxeles entre las columnas.
/PracticaDjango/Tienda/templates/Tienda/tienda.html
<div class="col-md-3">
...
</div>Creación de miniaturas de imagen usando easy-thumbnails
PracticaDjango/PracticaDjango/settings.py
INSTALLED_APPS = [
#...
# Aplicaciones de terceros
#...
'easy_thumbnails',PracticaDjango/Tienda/templates/Tienda/tienda.html
<!--Cargamos la plantilla base--> {% extends "Proyecto_web_app/base.html" %} {% load thumbnail %} <!-- ... --> <div class="tab-pane fade show active" id="ps4" role="tabpanel" aria-labelledby="ps4-tab"> <h3>Juegos PS4</h3> <div class="row g-4"> {% for producto in productos %} {% if producto.categoria_id == 1 %} <div class="col-md-3"> <div class="card h-100" style="width:200px"> <!-- <img class="card-img-top" src="{{producto.imagen.url}}" alt="Card image"> --> <img class="card-img-top" src="{% thumbnail producto.imagen 200x0 %}" alt="Card image"> <div class="card-body"> <h4 class="card-title">{{producto.nombre}}</h4> <p class="card-text">{{producto.precio}} €</p> </div> <div class="card-footer text-center"> <a href="{% url 'carro:agregar' producto.id %}" class="btn btn-success">Agregar al Carro</a> </div> </div> </div>




No hay comentarios:
Publicar un comentario