fix shop stuff

sync
Raz 8 months ago
parent 4be049db33
commit 47db5854d0
  1. 66
      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"]}') self.stdout.write(f'Created color: {color_data["name"]}')
else: else:
# Update existing colors with secondary color if needed # 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.secondary_hex_color = color_data['secondary_hex']
color.save() color.save()
self.stdout.write(f'Updated color: {color_data["name"]} with secondary color') self.stdout.write(f'Updated color: {color_data["name"]}')
else: else:
self.stdout.write(f'Color already exists: {color_data["name"]}') self.stdout.write(f'Color already exists: {color_data["name"]}')
@ -58,38 +59,46 @@ class Command(BaseCommand):
self.stdout.write('Creating products...') self.stdout.write('Creating products...')
products = [ products = [
{ {
'sku': 'PC001',
'title': 'Tennis Racket Pro', 'title': 'Tennis Racket Pro',
'description': 'Professional grade tennis racket with advanced stability control.',
'price': 99.99, 'price': 99.99,
'ordering_value': 1, 'ordering_value': 1,
'cut': 2, # Men 'cut': 2, # Men
'colors': ['Black', 'White', 'Red', 'Black/White'], 'colors': ['Black/White'],
'sizes': ['M', 'L', 'XL'], 'sizes': ['M', 'L', 'XL'],
'image_filename': 'hat.jpg' # Just the filename 'image_filename': 'hat.jpg'
}, },
{ {
'sku': 'PC002',
'title': 'Sports T-Shirt', 'title': 'Sports T-Shirt',
'description': 'Breathable sports t-shirt made with moisture-wicking fabric.',
'price': 29.99, 'price': 29.99,
'ordering_value': 2, 'ordering_value': 2,
'cut': 1, # Women 'cut': 1, # Women
'colors': ['Black', 'White', 'Blue', 'Red', 'Red/Blue'], 'colors': ['Black', 'White', 'Blue', 'Red', 'Red/Blue'],
'sizes': ['XS', 'S', 'M', 'L', 'XL'], 'sizes': ['XS', 'S', 'M', 'L', 'XL'],
'image_filename': 'tshirt.jpg' # Just the filename 'image_filename': 'tshirt.jpg'
}, },
{ {
'sku': 'PC003',
'title': 'Kids Tennis Shorts', 'title': 'Kids Tennis Shorts',
'description': 'Comfortable tennis shorts for kids with elastic waistband.',
'price': 19.99, 'price': 19.99,
'ordering_value': 3, 'ordering_value': 3,
'cut': 3, # Kids 'cut': 3, # Kids
'colors': ['Blue', 'White', 'Green/Yellow'], 'colors': ['Blue', 'White', 'Green/Yellow'],
'sizes': ['XS', 'S', 'M'], 'sizes': ['XS', 'S', 'M'],
'image_filename': 'kids_shorts.jpg' # Just the filename 'image_filename': 'kids_shorts.jpg'
} }
] ]
for product_data in products: for product_data in products:
product, created = Product.objects.get_or_create( product, created = Product.objects.update_or_create(
title=product_data['title'], sku=product_data['sku'],
defaults={ defaults={
'title': product_data['title'],
'description': product_data.get('description', ''),
'price': product_data['price'], 'price': product_data['price'],
'ordering_value': product_data['ordering_value'], 'ordering_value': product_data['ordering_value'],
'cut': product_data['cut'] 'cut': product_data['cut']
@ -97,35 +106,30 @@ class Command(BaseCommand):
) )
if created: if created:
self.stdout.write(f'Created product: {product_data["title"]}') self.stdout.write(f'Created product: {product_data["sku"]} - {product_data["title"]}')
else:
# Add colors self.stdout.write(f'Updated product: {product_data["sku"]} - {product_data["title"]}')
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])
# Construct the full path for storage # Handle the image path
if 'image_filename' in product_data and product_data['image_filename']: 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']}" image_path = f"{settings.STATIC_URL}shop/images/products/{product_data['image_filename']}"
print(image_path) if product.image != image_path:
# Store this path in the database
product.image = image_path product.image = image_path
product.save() 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"]}') # Update colors - first clear existing then add new ones
else: product.colors.clear()
self.stdout.write(f'Product already exists: {product_data["title"]}')
# 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']: for color_name in product_data['colors']:
if color_name not in existing_colors: if color_name in color_objects:
product.colors.add(color_objects[color_name]) product.colors.add(color_objects[color_name])
self.stdout.write(f'Added color {color_name} to existing product: {product_data["title"]}') self.stdout.write(f'Updated colors for: {product_data["sku"]}')
# 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 return self.name
class Product(models.Model): class Product(models.Model):
sku = models.CharField(max_length=50, unique=True, help_text="Product SKU (unique identifier)")
title = models.CharField(max_length=200) 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) image = models.CharField(max_length=200, null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00) 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 ordering = ['ordering_value', 'cut'] # Add this line to sort by title
def __str__(self): def __str__(self):
return self.title return f"{self.sku} - {self.title}"
class CartItem(models.Model): class CartItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)

@ -40,29 +40,40 @@
background-color: blue; 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 { .option-element.product-price {
grid-column: 2; grid-column: 2;
grid-row: 2; grid-row: 3;
text-align: center; text-align: center;
background-color: green; background-color: green;
} }
.option-element.color-label { .option-element.color-label {
grid-column: 1; grid-column: 1;
grid-row: 2; grid-row: 3;
font-size: 12px; font-size: 14px;
background-color: yellow; background-color: yellow;
} }
.option-element.color-selector { .option-element.color-selector {
grid-column: 1; grid-column: 1;
grid-row: 3; grid-row: 4;
background-color: red; background-color: red;
} }
.option-element.size-selector { .option-element.size-selector {
grid-column: 2; grid-column: 2;
grid-row: 3; grid-row: 4;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
background-color: purple; background-color: purple;
@ -70,12 +81,12 @@
.option-element.quantity-selector { .option-element.quantity-selector {
grid-column: 1; grid-column: 1;
grid-row: 4; grid-row: 5;
} }
.option-element.total-price { .option-element.total-price {
grid-column: 2; grid-column: 2;
grid-row: 4; grid-row: 5;
text-align: center; text-align: center;
} }
@ -156,7 +167,6 @@
.cart-table th, .cart-table th,
.cart-table td { .cart-table td {
padding: 10px;
text-align: center; text-align: center;
} }
@ -381,15 +391,6 @@ v .cart-table {
.cart-table td { .cart-table td {
display: flex; 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 { .cart-table td.product-name {
@ -399,24 +400,24 @@ v .cart-table {
font-size: 1.1em; font-size: 1.1em;
} }
.cart-table td.product-color { .cart-table td.product-description {
grid-column: 1 / span 2; grid-column: 1 / span 3;
grid-row: 2; grid-row: 2;
} }
/* .cart-table td.product-size { .cart-table td.product-color {
grid-column: 2; grid-column: 1 / span 2;
grid-row: 2; grid-row: 3;
} */ }
.cart-table td.product-quantity { .cart-table td.product-quantity {
grid-column: 1; grid-column: 1;
grid-row: 3; grid-row: 4;
} }
.cart-table td.product-price { .cart-table td.product-price {
grid-column: 3; grid-column: 3;
grid-row: 3; grid-row: 4;
justify-content: right; justify-content: right;
} }

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

@ -11,6 +11,12 @@
<div class="option-element product-title"> <div class="option-element product-title">
{{ product.title }} {{ product.title }}
</div> </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 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-label"><span id="selected-color-name-{{ product.id }}">{{ product.colors.all.0.name }}</span></div>
<div class="option-element color-selector form-group"> <div class="option-element color-selector form-group">

@ -419,6 +419,7 @@ def prepare_item_display_data(items, is_cart=True):
item_data = { item_data = {
'id': item.id, 'id': item.id,
'product_title': item.product.title, '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_name': item.color.name if item.color else 'N/A',
'color_hex': item.color.colorHex if item.color else '#FFFFFF', '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, '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 = { item_data = {
'id': item.id, 'id': item.id,
'product_title': item.product.title, '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_name': item.color.name if item.color else 'N/A',
'color_hex': item.color.colorHex if item.color else '#FFFFFF', '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, 'secondary_color_hex': item.color.secondary_hex_color if item.color and item.color.secondary_hex_color else None,

Loading…
Cancel
Save