fix shop stuff

sync
Raz 8 months ago
parent 4be049db33
commit 47db5854d0
  1. 72
      shop/management/commands/create_initial_shop_data.py
  2. 18
      shop/migrations/0019_product_description.py
  3. 18
      shop/migrations/0020_product_sku.py
  4. 4
      shop/models.py
  5. 51
      shop/static/shop/css/shop.css
  6. 3
      shop/templates/shop/partials/order_items_display.html
  7. 6
      shop/templates/shop/product_item.html
  8. 2
      shop/views.py

@ -34,10 +34,11 @@ class Command(BaseCommand):
self.stdout.write(f'Created color: {color_data["name"]}')
else:
# Update existing colors with secondary color if needed
if color.secondary_hex_color != color_data['secondary_hex']:
if color.colorHex != color_data['hex'] or color.secondary_hex_color != color_data['secondary_hex']:
color.colorHex = color_data['hex']
color.secondary_hex_color = color_data['secondary_hex']
color.save()
self.stdout.write(f'Updated color: {color_data["name"]} with secondary color')
self.stdout.write(f'Updated color: {color_data["name"]}')
else:
self.stdout.write(f'Color already exists: {color_data["name"]}')
@ -58,38 +59,46 @@ class Command(BaseCommand):
self.stdout.write('Creating products...')
products = [
{
'sku': 'PC001',
'title': 'Tennis Racket Pro',
'description': 'Professional grade tennis racket with advanced stability control.',
'price': 99.99,
'ordering_value': 1,
'cut': 2, # Men
'colors': ['Black', 'White', 'Red', 'Black/White'],
'colors': ['Black/White'],
'sizes': ['M', 'L', 'XL'],
'image_filename': 'hat.jpg' # Just the filename
'image_filename': 'hat.jpg'
},
{
'sku': 'PC002',
'title': 'Sports T-Shirt',
'description': 'Breathable sports t-shirt made with moisture-wicking fabric.',
'price': 29.99,
'ordering_value': 2,
'cut': 1, # Women
'colors': ['Black', 'White', 'Blue', 'Red', 'Red/Blue'],
'sizes': ['XS', 'S', 'M', 'L', 'XL'],
'image_filename': 'tshirt.jpg' # Just the filename
'image_filename': 'tshirt.jpg'
},
{
'sku': 'PC003',
'title': 'Kids Tennis Shorts',
'description': 'Comfortable tennis shorts for kids with elastic waistband.',
'price': 19.99,
'ordering_value': 3,
'cut': 3, # Kids
'colors': ['Blue', 'White', 'Green/Yellow'],
'sizes': ['XS', 'S', 'M'],
'image_filename': 'kids_shorts.jpg' # Just the filename
'image_filename': 'kids_shorts.jpg'
}
]
for product_data in products:
product, created = Product.objects.get_or_create(
title=product_data['title'],
product, created = Product.objects.update_or_create(
sku=product_data['sku'],
defaults={
'title': product_data['title'],
'description': product_data.get('description', ''),
'price': product_data['price'],
'ordering_value': product_data['ordering_value'],
'cut': product_data['cut']
@ -97,35 +106,30 @@ class Command(BaseCommand):
)
if created:
self.stdout.write(f'Created product: {product_data["title"]}')
# Add colors
for color_name in product_data['colors']:
product.colors.add(color_objects[color_name])
# Add sizes
for size_name in product_data['sizes']:
product.sizes.add(size_objects[size_name])
self.stdout.write(f'Created product: {product_data["sku"]} - {product_data["title"]}')
else:
self.stdout.write(f'Updated product: {product_data["sku"]} - {product_data["title"]}')
# Construct the full path for storage
if 'image_filename' in product_data and product_data['image_filename']:
# Construct the URL path to the image
# This uses STATIC_URL from your settings
image_path = f"{settings.STATIC_URL}shop/images/products/{product_data['image_filename']}"
print(image_path)
# Store this path in the database
# Handle the image path
if 'image_filename' in product_data and product_data['image_filename']:
image_path = f"{settings.STATIC_URL}shop/images/products/{product_data['image_filename']}"
if product.image != image_path:
product.image = image_path
product.save()
self.stdout.write(f'Updated image path to "{image_path}" for: {product_data["sku"]}')
self.stdout.write(f'Added image path "{image_path}" for: {product_data["title"]}')
else:
self.stdout.write(f'Product already exists: {product_data["title"]}')
# Update colors - first clear existing then add new ones
product.colors.clear()
for color_name in product_data['colors']:
if color_name in color_objects:
product.colors.add(color_objects[color_name])
self.stdout.write(f'Updated colors for: {product_data["sku"]}')
# Update existing products with new colors if needed
existing_colors = set(product.colors.all().values_list('name', flat=True))
for color_name in product_data['colors']:
if color_name not in existing_colors:
product.colors.add(color_objects[color_name])
self.stdout.write(f'Added color {color_name} to existing product: {product_data["title"]}')
# Update sizes - first clear existing then add new ones
product.sizes.clear()
for size_name in product_data['sizes']:
if size_name in size_objects:
product.sizes.add(size_objects[size_name])
self.stdout.write(f'Updated sizes for: {product_data["sku"]}')
self.stdout.write(self.style.SUCCESS('Successfully created initial shop data'))
self.stdout.write(self.style.SUCCESS('Successfully created/updated shop data'))

@ -0,0 +1,18 @@
# Generated by Django 4.2.11 on 2025-03-21 12:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0018_color_secondary_hex_color'),
]
operations = [
migrations.AddField(
model_name='product',
name='description',
field=models.TextField(blank=True, help_text='Product description text', null=True),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.11 on 2025-03-21 12:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0019_product_description'),
]
operations = [
migrations.AddField(
model_name='product',
name='sku',
field=models.CharField(default='PC000', help_text='Product SKU (unique identifier)', max_length=50, unique=True),
),
]

@ -29,7 +29,9 @@ class Size(models.Model):
return self.name
class Product(models.Model):
sku = models.CharField(max_length=50, unique=True, help_text="Product SKU (unique identifier)")
title = models.CharField(max_length=200)
description = models.TextField(blank=True, null=True, help_text="Product description text")
image = models.CharField(max_length=200, null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
@ -43,7 +45,7 @@ class Product(models.Model):
ordering = ['ordering_value', 'cut'] # Add this line to sort by title
def __str__(self):
return self.title
return f"{self.sku} - {self.title}"
class CartItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)

@ -40,29 +40,40 @@
background-color: blue;
}
.option-element.product-description {
grid-column: 1 / span 2;
grid-row: 2;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; /* limit to 2 lines */
-webkit-box-orient: vertical;
}
.option-element.product-price {
grid-column: 2;
grid-row: 2;
grid-row: 3;
text-align: center;
background-color: green;
}
.option-element.color-label {
grid-column: 1;
grid-row: 2;
font-size: 12px;
grid-row: 3;
font-size: 14px;
background-color: yellow;
}
.option-element.color-selector {
grid-column: 1;
grid-row: 3;
grid-row: 4;
background-color: red;
}
.option-element.size-selector {
grid-column: 2;
grid-row: 3;
grid-row: 4;
font-size: 12px;
text-align: center;
background-color: purple;
@ -70,12 +81,12 @@
.option-element.quantity-selector {
grid-column: 1;
grid-row: 4;
grid-row: 5;
}
.option-element.total-price {
grid-column: 2;
grid-row: 4;
grid-row: 5;
text-align: center;
}
@ -156,7 +167,6 @@
.cart-table th,
.cart-table td {
padding: 10px;
text-align: center;
}
@ -381,15 +391,6 @@ v .cart-table {
.cart-table td {
display: flex;
/* padding: 8px 5px;
text-align: right;
justify-content: space-between;
align-items: center; */
}
.cart-table .price-column,
.cart-table .text-left {
/* text-align: right !important; */
}
.cart-table td.product-name {
@ -399,24 +400,24 @@ v .cart-table {
font-size: 1.1em;
}
.cart-table td.product-color {
grid-column: 1 / span 2;
.cart-table td.product-description {
grid-column: 1 / span 3;
grid-row: 2;
}
/* .cart-table td.product-size {
grid-column: 2;
grid-row: 2;
} */
.cart-table td.product-color {
grid-column: 1 / span 2;
grid-row: 3;
}
.cart-table td.product-quantity {
grid-column: 1;
grid-row: 3;
grid-row: 4;
}
.cart-table td.product-price {
grid-column: 3;
grid-row: 3;
grid-row: 4;
justify-content: right;
}

@ -3,6 +3,9 @@
{% for item in items %}
<tr class="{% cycle 'odd-row' 'even-row' %}">
<td class="text-left product-name" data-label="Produit">{{ item.product_title }}</td>
{% if item.product_description %}
<td class="text-left product-description" data-label="Description">{{ item.product_description }}</td>
{% endif %}
<td class="product-color" data-label="Couleur">
<div class="color-display">
<div class="color-sample-cart"

@ -11,6 +11,12 @@
<div class="option-element product-title">
{{ product.title }}
</div>
{% if product.description %}
<div class="option-element product-description">
{{ product.description }}
</div>
{% endif %}
<div class="option-element product-price">{{ product.price }} €</div>
<div class="option-element color-label"><span id="selected-color-name-{{ product.id }}">{{ product.colors.all.0.name }}</span></div>
<div class="option-element color-selector form-group">

@ -419,6 +419,7 @@ def prepare_item_display_data(items, is_cart=True):
item_data = {
'id': item.id,
'product_title': item.product.title,
'product_description': item.product.description if item.product.description else None,
'color_name': item.color.name if item.color else 'N/A',
'color_hex': item.color.colorHex if item.color else '#FFFFFF',
'secondary_color_hex': item.color.secondary_hex_color if item.color and item.color.secondary_hex_color else None,
@ -432,6 +433,7 @@ def prepare_item_display_data(items, is_cart=True):
item_data = {
'id': item.id,
'product_title': item.product.title,
'product_description': item.product.description if item.product.description else None,
'color_name': item.color.name if item.color else 'N/A',
'color_hex': item.color.colorHex if item.color else '#FFFFFF',
'secondary_color_hex': item.color.secondary_hex_color if item.color and item.color.secondary_hex_color else None,

Loading…
Cancel
Save