Add variant photo assoc

This commit is contained in:
Nathan Chapman 2022-11-05 20:35:16 -06:00
parent 4b8831035e
commit 0e52e1bdfe
6 changed files with 74 additions and 25 deletions

View File

@ -10,6 +10,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -25,6 +26,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -40,6 +42,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -55,6 +58,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -70,6 +74,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -85,6 +90,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -100,6 +106,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -115,6 +122,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -130,6 +138,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -145,6 +154,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -160,6 +170,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -175,6 +186,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -190,6 +202,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -205,6 +218,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -220,6 +234,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -235,6 +250,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -250,6 +266,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 1, "sorting": 1,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }
@ -265,6 +282,7 @@
"track_inventory": false, "track_inventory": false,
"stock": null, "stock": null,
"sorting": 3, "sorting": 3,
"image": null,
"created_at": "2022-02-23T18:06:57.624Z", "created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-02-23T18:06:57.624Z" "updated_at": "2022-02-23T18:06:57.624Z"
} }

View File

@ -121,6 +121,29 @@ class Product(models.Model):
ordering = ['sorting', 'name'] ordering = ['sorting', 'name']
class ProductPhoto(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/images')
def __str__(self):
return f'{self.product.name} {self.image}'
def delete(self, *args, **kwargs):
storage, path = self.image.storage, self.image.path
super(ProductPhoto, self).delete(*args, **kwargs)
storage.delete(path)
# def save(self, *args, **kwargs):
# super().save(*args, **kwargs)
# img = Image.open(self.image.path)
# if img.height > 400 or img.width > 400:
# output_size = (400, 400)
# img.thumbnail(output_size)
# img.save(self.image.path)
class ProductVariantManager(models.Manager): class ProductVariantManager(models.Manager):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().annotate( return super().get_queryset().annotate(
@ -135,7 +158,7 @@ class ProductVariant(models.Model):
related_name='variants' related_name='variants'
) )
image = models.ForeignKey( image = models.ForeignKey(
'ProductPhoto', ProductPhoto,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
related_name='+', related_name='+',
null=True null=True
@ -195,29 +218,6 @@ class ProductOption(models.Model):
return f'{self.name}' return f'{self.name}'
class ProductPhoto(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/images')
def __str__(self):
return self.product.name
def delete(self, *args, **kwargs):
storage, path = self.image.storage, self.image.path
super(ProductPhoto, self).delete(*args, **kwargs)
storage.delete(path)
# def save(self, *args, **kwargs):
# super().save(*args, **kwargs)
# img = Image.open(self.image.path)
# if img.height > 400 or img.width > 400:
# output_size = (400, 400)
# img.thumbnail(output_size)
# img.save(self.image.path)
class Coupon(models.Model): class Coupon(models.Model):
type = models.CharField( type = models.CharField(
max_length=20, max_length=20,

View File

@ -3,6 +3,7 @@ from django import forms
from core import OrderStatus from core import OrderStatus
from core.models import ( from core.models import (
ProductVariant,
Order, Order,
OrderLine, OrderLine,
ShippingRate, ShippingRate,
@ -14,6 +15,27 @@ from core.models import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ProductVariantUpdateForm(forms.ModelForm):
class Meta:
model = ProductVariant
fields = [
'name',
'sku',
'price',
'weight',
'track_inventory',
'stock',
'image'
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance:
self.fields['image'].queryset = ProductPhoto.objects.filter(
product=self.instance.product
)
class CouponForm(forms.ModelForm): class CouponForm(forms.ModelForm):
class Meta: class Meta:
model = Coupon model = Coupon

View File

@ -25,7 +25,11 @@
<div class="object__item object__item--col5"> <div class="object__item object__item--col5">
{% with product=item.variant.product %} {% with product=item.variant.product %}
<figure class="item__figure"> <figure class="item__figure">
<img class="product__image product__image--small" src="{{product.get_first_img.image.url}}" alt="{{product.get_first_img.image}}"> {% if item.variant.image %}
<img class="item__image" src="{{item.variant.image.image.url}}" alt="{{item.variant.image.image}}">
{% else %}
<img class="item__image" src="{{product.get_first_img.image.url}}" alt="{{product.get_first_img.image}}">
{% endif %}
<figcaption><strong>{{item.variant}}</strong><br>{{item.customer_note}}</figcaption> <figcaption><strong>{{item.variant}}</strong><br>{{item.customer_note}}</figcaption>
</figure> </figure>
<span>{{product.sku}}</span> <span>{{product.sku}}</span>

View File

@ -19,7 +19,11 @@
<div class="object__item object__item--col5"> <div class="object__item object__item--col5">
{% with product=variant.product %} {% with product=variant.product %}
<figure class="item__figure"> <figure class="item__figure">
{% if variant.image %}
<img class="item__image" src="{{variant.image.image.url}}" alt="{{variant.image.image}}">
{% else %}
<img class="product__image product__image--small" src="{{product.get_first_img.image.url}}" alt="{{product.get_first_img.image}}"> <img class="product__image product__image--small" src="{{product.get_first_img.image.url}}" alt="{{product.get_first_img.image}}">
{% endif %}
<figcaption><strong>{{variant}}</strong></figcaption> <figcaption><strong>{{variant}}</strong></figcaption>
</figure> </figure>
<span>{{ variant.sku }}</span> <span>{{ variant.sku }}</span>

View File

@ -2,6 +2,7 @@ import logging
from datetime import datetime from datetime import datetime
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django import forms
from django.shortcuts import render, reverse, redirect, get_object_or_404 from django.shortcuts import render, reverse, redirect, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy