Изменение структуры хранения изображений и исправление ошибки дублирования ID
This commit is contained in:
@@ -909,7 +909,7 @@ class ProductPhoto(models.Model):
|
||||
"""
|
||||
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='photos',
|
||||
verbose_name="Товар")
|
||||
image = models.ImageField(upload_to='products/originals/', verbose_name="Оригинальное фото")
|
||||
image = models.ImageField(upload_to='products/temp/', verbose_name="Оригинальное фото")
|
||||
order = models.PositiveIntegerField(default=0, verbose_name="Порядок")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
|
||||
|
||||
@@ -928,31 +928,45 @@ class ProductPhoto(models.Model):
|
||||
from .utils.image_processor import ImageProcessor
|
||||
|
||||
is_new = not self.pk
|
||||
old_image_path = None
|
||||
|
||||
# Если это обновление существующего объекта, сохраняем старый путь для удаления
|
||||
if not is_new:
|
||||
try:
|
||||
old_obj = ProductPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Если было загружено новое изображение
|
||||
if self.image and (is_new or old_image_path):
|
||||
# Обрабатываем изображение с использованием slug товара как идентификатора
|
||||
# slug гарантирует уникальность и читаемость имени файла
|
||||
identifier = self.product.slug
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'products', identifier=identifier)
|
||||
# Сохраняем только путь к оригиналу в поле image
|
||||
# Если это новый объект с изображением, нужно сначала сохранить без изображения, чтобы получить ID
|
||||
if is_new and self.image:
|
||||
# Сохраняем объект без изображения, чтобы получить ID
|
||||
temp_image = self.image
|
||||
self.image = None
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Теперь обрабатываем изображение с известными ID
|
||||
processed_paths = ImageProcessor.process_image(temp_image, 'products', entity_id=self.product.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии и дублирования ID
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Проверяем старый путь для удаления, если это обновление
|
||||
old_image_path = None
|
||||
if self.pk:
|
||||
try:
|
||||
old_obj = ProductPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Проверяем, нужно ли обрабатывать изображение
|
||||
if self.image and old_image_path:
|
||||
# Обновление существующего изображения
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'products', entity_id=self.product.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Удаляем старые версии если это обновление
|
||||
if old_image_path:
|
||||
ImageProcessor.delete_all_versions('products', old_image_path)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
# Удаляем старые версии
|
||||
ImageProcessor.delete_all_versions('products', old_image_path, entity_id=self.product.id, photo_id=self.id)
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Просто сохраняем без обработки изображения
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Удаляет все версии изображения при удалении фото"""
|
||||
@@ -964,7 +978,7 @@ class ProductPhoto(models.Model):
|
||||
if self.image:
|
||||
try:
|
||||
logger.info(f"[ProductPhoto.delete] Удаляем изображение: {self.image.name}")
|
||||
ImageProcessor.delete_all_versions('products', self.image.name)
|
||||
ImageProcessor.delete_all_versions('products', self.image.name, entity_id=self.product.id, photo_id=self.id)
|
||||
logger.info(f"[ProductPhoto.delete] ✓ Все версии изображения удалены")
|
||||
except Exception as e:
|
||||
logger.error(f"[ProductPhoto.delete] ✗ Ошибка при удалении версий: {str(e)}", exc_info=True)
|
||||
@@ -999,7 +1013,7 @@ class ProductKitPhoto(models.Model):
|
||||
"""
|
||||
kit = models.ForeignKey(ProductKit, on_delete=models.CASCADE, related_name='photos',
|
||||
verbose_name="Комплект")
|
||||
image = models.ImageField(upload_to='kits/originals/', verbose_name="Оригинальное фото")
|
||||
image = models.ImageField(upload_to='kits/temp/', verbose_name="Оригинальное фото")
|
||||
order = models.PositiveIntegerField(default=0, verbose_name="Порядок")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
|
||||
|
||||
@@ -1018,31 +1032,45 @@ class ProductKitPhoto(models.Model):
|
||||
from .utils.image_processor import ImageProcessor
|
||||
|
||||
is_new = not self.pk
|
||||
old_image_path = None
|
||||
|
||||
# Если это обновление существующего объекта, сохраняем старый путь для удаления
|
||||
if not is_new:
|
||||
try:
|
||||
old_obj = ProductKitPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductKitPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Если было загружено новое изображение
|
||||
if self.image and (is_new or old_image_path):
|
||||
# Обрабатываем изображение с использованием slug комплекта как идентификатора
|
||||
# slug гарантирует уникальность и читаемость имени файла
|
||||
identifier = self.kit.slug
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'kits', identifier=identifier)
|
||||
# Сохраняем только путь к оригиналу в поле image
|
||||
# Если это новый объект с изображением, нужно сначала сохранить без изображения, чтобы получить ID
|
||||
if is_new and self.image:
|
||||
# Сохраняем объект без изображения, чтобы получить ID
|
||||
temp_image = self.image
|
||||
self.image = None
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Теперь обрабатываем изображение с известными ID
|
||||
processed_paths = ImageProcessor.process_image(temp_image, 'kits', entity_id=self.kit.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии и дублирования ID
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Проверяем старый путь для удаления, если это обновление
|
||||
old_image_path = None
|
||||
if self.pk:
|
||||
try:
|
||||
old_obj = ProductKitPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductKitPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Проверяем, нужно ли обрабатывать изображение
|
||||
if self.image and old_image_path:
|
||||
# Обновление существующего изображения
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'kits', entity_id=self.kit.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Удаляем старые версии если это обновление
|
||||
if old_image_path:
|
||||
ImageProcessor.delete_all_versions('kits', old_image_path)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
# Удаляем старые версии
|
||||
ImageProcessor.delete_all_versions('kits', old_image_path, entity_id=self.kit.id, photo_id=self.id)
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Просто сохраняем без обработки изображения
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Удаляет все версии изображения при удалении фото"""
|
||||
@@ -1054,7 +1082,7 @@ class ProductKitPhoto(models.Model):
|
||||
if self.image:
|
||||
try:
|
||||
logger.info(f"[ProductKitPhoto.delete] Удаляем изображение: {self.image.name}")
|
||||
ImageProcessor.delete_all_versions('kits', self.image.name)
|
||||
ImageProcessor.delete_all_versions('kits', self.image.name, entity_id=self.kit.id, photo_id=self.id)
|
||||
logger.info(f"[ProductKitPhoto.delete] ✓ Все версии изображения удалены")
|
||||
except Exception as e:
|
||||
logger.error(f"[ProductKitPhoto.delete] ✗ Ошибка при удалении версий: {str(e)}", exc_info=True)
|
||||
@@ -1089,7 +1117,7 @@ class ProductCategoryPhoto(models.Model):
|
||||
"""
|
||||
category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, related_name='photos',
|
||||
verbose_name="Категория")
|
||||
image = models.ImageField(upload_to='categories/originals/', verbose_name="Оригинальное фото")
|
||||
image = models.ImageField(upload_to='categories/temp/', verbose_name="Оригинальное фото")
|
||||
order = models.PositiveIntegerField(default=0, verbose_name="Порядок")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
|
||||
|
||||
@@ -1108,31 +1136,45 @@ class ProductCategoryPhoto(models.Model):
|
||||
from .utils.image_processor import ImageProcessor
|
||||
|
||||
is_new = not self.pk
|
||||
old_image_path = None
|
||||
|
||||
# Если это обновление существующего объекта, сохраняем старый путь для удаления
|
||||
if not is_new:
|
||||
try:
|
||||
old_obj = ProductCategoryPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductCategoryPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Если было загружено новое изображение
|
||||
if self.image and (is_new or old_image_path):
|
||||
# Обрабатываем изображение с использованием slug категории как идентификатора
|
||||
# slug гарантирует уникальность и читаемость имени файла
|
||||
identifier = self.category.slug
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'categories', identifier=identifier)
|
||||
# Сохраняем только путь к оригиналу в поле image
|
||||
# Если это новый объект с изображением, нужно сначала сохранить без изображения, чтобы получить ID
|
||||
if is_new and self.image:
|
||||
# Сохраняем объект без изображения, чтобы получить ID
|
||||
temp_image = self.image
|
||||
self.image = None
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Теперь обрабатываем изображение с известными ID
|
||||
processed_paths = ImageProcessor.process_image(temp_image, 'categories', entity_id=self.category.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии и дублирования ID
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Проверяем старый путь для удаления, если это обновление
|
||||
old_image_path = None
|
||||
if self.pk:
|
||||
try:
|
||||
old_obj = ProductCategoryPhoto.objects.get(pk=self.pk)
|
||||
if old_obj.image and old_obj.image != self.image:
|
||||
old_image_path = old_obj.image.name
|
||||
except ProductCategoryPhoto.DoesNotExist:
|
||||
pass
|
||||
|
||||
# Проверяем, нужно ли обрабатывать изображение
|
||||
if self.image and old_image_path:
|
||||
# Обновление существующего изображения
|
||||
processed_paths = ImageProcessor.process_image(self.image, 'categories', entity_id=self.category.id, photo_id=self.id)
|
||||
self.image = processed_paths['original']
|
||||
|
||||
# Удаляем старые версии если это обновление
|
||||
if old_image_path:
|
||||
ImageProcessor.delete_all_versions('categories', old_image_path)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
# Удаляем старые версии
|
||||
ImageProcessor.delete_all_versions('categories', old_image_path, entity_id=self.category.id, photo_id=self.id)
|
||||
|
||||
# Обновляем только поле image, чтобы избежать рекурсии
|
||||
super().save(update_fields=['image'])
|
||||
else:
|
||||
# Просто сохраняем без обработки изображения
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""Удаляет все версии изображения при удалении фото"""
|
||||
@@ -1144,7 +1186,7 @@ class ProductCategoryPhoto(models.Model):
|
||||
if self.image:
|
||||
try:
|
||||
logger.info(f"[ProductCategoryPhoto.delete] Удаляем изображение: {self.image.name}")
|
||||
ImageProcessor.delete_all_versions('categories', self.image.name)
|
||||
ImageProcessor.delete_all_versions('categories', self.image.name, entity_id=self.category.id, photo_id=self.id)
|
||||
logger.info(f"[ProductCategoryPhoto.delete] ✓ Все версии изображения удалены")
|
||||
except Exception as e:
|
||||
logger.error(f"[ProductCategoryPhoto.delete] ✗ Ошибка при удалении версий: {str(e)}", exc_info=True)
|
||||
|
||||
Reference in New Issue
Block a user