Add those files
This commit is contained in:
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
# Generated by Django 6.0.1 on 2026-02-16 11:57
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tienda', '0011_ordermessage'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='alt',
|
||||
field=models.CharField(blank=True, default='', max_length=255, verbose_name='Texto alternativo'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ShippingAddress',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('full_name', models.CharField(max_length=200, verbose_name='Nombre completo')),
|
||||
('address_line_1', models.CharField(max_length=250, verbose_name='Dirección')),
|
||||
('address_line_2', models.CharField(blank=True, max_length=250, verbose_name='Dirección (línea 2)')),
|
||||
('city', models.CharField(max_length=100, verbose_name='Ciudad')),
|
||||
('postal_code', models.CharField(max_length=20, verbose_name='Código postal')),
|
||||
('country', models.CharField(default='España', max_length=100, verbose_name='País')),
|
||||
('phone', models.CharField(max_length=20, verbose_name='Teléfono')),
|
||||
('is_default', models.BooleanField(default=False, verbose_name='Dirección predeterminada')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shipping_addresses', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Dirección de envío',
|
||||
'verbose_name_plural': 'Direcciones de envío',
|
||||
'ordering': ['-is_default', '-created_at'],
|
||||
},
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@@ -12,6 +12,7 @@ class Category(models.Model):
|
||||
class Image(models.Model):
|
||||
name = models.CharField(max_length=200, default="")
|
||||
image = models.ImageField(upload_to='images/')
|
||||
alt = models.CharField(max_length=255, default="", blank=True, verbose_name="Texto alternativo")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load static %}
|
||||
{% load compress %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@@ -102,7 +102,7 @@
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<a href="{% url 'mis_productos' %}" class="nav-link btn btn-outline-secondary btn-sm">Panel Vendedor</a>
|
||||
<span class="nav-text d-none d-md-inline text-muted">{{ user.first_name|default:user.username }}</span>
|
||||
<span class="nav-text d-none d-md-inline text-white">{{ user.first_name|default:user.username }}</span>
|
||||
<a href="{% url 'logout' %}" class="nav-link btn btn-primary btn-sm">Cerrar Sesión</a>
|
||||
{% else %}
|
||||
<a href="{% url 'login' %}" class="nav-link btn btn-primary btn-sm">Iniciar Sesión</a>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
{% if item.product.primary_image %}
|
||||
<img src="/media/{{ item.product.primary_image.image }}" alt="{{ item.product.name }}" style="width: 50px; height: 50px; object-fit: cover;" class="me-3">
|
||||
<img src="/media/{{ item.product.primary_image.image }}" alt="{{ item.product.primary_image.alt|default:item.product.name }}" style="width: 50px; height: 50px; object-fit: cover;" class="me-3">
|
||||
{% endif %}
|
||||
<a href="{% url 'producto' item.product.id %}">{{ item.product.name }}</a>
|
||||
</div>
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card product-card h-100">
|
||||
{% if product.primary_image %}
|
||||
<img src="{{ product.primary_image.image.url }}" class="card-img-top" alt="{{ product.name }}" style="height: 250px; object-fit: cover;">
|
||||
<img src="{{ product.primary_image.image.url }}" class="card-img-top" alt="{{ product.primary_image.alt|default:product.name }}" style="height: 250px; object-fit: cover;">
|
||||
{% else %}
|
||||
<div class="card-img-top bg-light d-flex align-items-center justify-content-center" style="height: 250px;">
|
||||
<span class="text-muted">Sin imagen</span>
|
||||
@@ -164,7 +164,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h5 class="card-title">{{ product.name }}</h5>
|
||||
<h3 class="card-title">{{ product.name }}</h3>
|
||||
|
||||
{% if product.briefdesc %}
|
||||
<p class="card-text text-muted small">{{ product.briefdesc|truncatewords:10 }}</p>
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
{% if products %}
|
||||
{% for producto in products %}
|
||||
<div class="card card-producto mt-5" style="width: 18rem;">
|
||||
<img src="/media/{{ producto.primary_image.image}}" class="card-img-top" alt="{{ producto.name }}">
|
||||
<img src="/media/{{ producto.primary_image.image}}" class="card-img-top" alt="{{ producto.primary_image.alt|default:producto.name }}">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ producto.name }}</h5>
|
||||
<h3 class="card-title">{{ producto.name }}</h3>
|
||||
<div class="card-text price-info mb-3">
|
||||
<small class="text-muted d-block">Sin IVA: €{{ producto.price|format_price }}</small>
|
||||
<p class="price mb-0">IVA incl: €{{ producto.get_price_with_vat|format_price }}</p>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
{% if producto.primary_image %}
|
||||
<img src="{{ producto.primary_image.image.url }}" alt="{{ producto.name }}" class="rounded" style="width: 70px; height: 70px; object-fit: cover;">
|
||||
<img src="{{ producto.primary_image.image.url }}" alt="{{ producto.primary_image.alt|default:producto.name }}" class="rounded" style="width: 70px; height: 70px; object-fit: cover;">
|
||||
{% else %}
|
||||
<div class="bg-secondary d-flex align-items-center justify-content-center rounded" style="width: 70px; height: 70px;">
|
||||
<span class="text-white small">Sin</span>
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
<div id="carouselProducto" class="carousel slide">
|
||||
<div class="carousel-inner">
|
||||
<div class="carousel-item active">
|
||||
<img src="/media/{{ product.primary_image.image }}" class="d-block w-100">
|
||||
<img src="/media/{{ product.primary_image.image }}" class="d-block w-100" alt="{{ product.primary_image.alt|default:product.name }}">
|
||||
</div>
|
||||
{% for image in product.secondary_images.all %}
|
||||
<div class="carousel-item">
|
||||
<img src="/media/{{ image.image }}" class="d-block w-100">
|
||||
<img src="/media/{{ image.image }}" class="d-block w-100" alt="{{ image.alt|default:product.name }}">
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<div class="col-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="card product-card h-100">
|
||||
{% if product.primary_image %}
|
||||
<img src="{{ product.primary_image.image.url }}" class="card-img-top" alt="{{ product.name }}" style="height: 250px; object-fit: cover;">
|
||||
<img src="{{ product.primary_image.image.url }}" class="card-img-top" alt="{{ product.primary_image.alt|default:product.name }}" style="height: 250px; object-fit: cover;">
|
||||
{% else %}
|
||||
<div class="card-img-top bg-light d-flex align-items-center justify-content-center" style="height: 250px;">
|
||||
<span class="text-muted">Sin imagen</span>
|
||||
|
||||
Reference in New Issue
Block a user