Изменение структуры хранения изображений и исправление ошибки дублирования ID

This commit is contained in:
2025-10-25 19:21:32 +03:00
parent 2f557f3f9b
commit a55d0405ed
3 changed files with 274 additions and 153 deletions

View File

@@ -54,16 +54,16 @@ class ImageService:
"""
Получает URL изображения нужного размера.
Работает с новым форматом имён файлов с поддержкой разных расширений:
- robot-50cm_1729611234567_original.jpg (JPEG, оригинал)
- robot-50cm_1729611234567_large.webp (WebP)
- robot-50cm_1729611234567_medium.webp (WebP)
- robot-50cm_1729611234567_thumbnail.webp (WebP)
Работает с новой структурой:
- products/<entity_id>/<photo_id>/original.jpg
- products/<entity_id>/<photo_id>/large.webp
- products/<entity_id>/<photo_id>/medium.webp
- products/<entity_id>/<photo_id>/thumb.webp
Args:
original_image_path: Путь к оригинальному файлу (из models.image)
Обычно это путь к файлу 'original'
Пример: products/originals/robot-50cm_1729611234567_original.jpg
Пример: products/123/456/original.jpg
size: Размер ('original', 'large', 'medium', 'thumbnail')
По умолчанию 'medium'
@@ -74,18 +74,70 @@ class ImageService:
return ''
try:
# Извлекаем имя файла и базовый путь
# Работаем с новой структурой: products/<entity_id>/<photo_id>/original.jpg
path_str = str(original_image_path)
parts = path_str.split('/')
if len(parts) >= 3:
# Извлекаем base_path, entity_id, photo_id из пути
base_path = parts[0] # products, kits, categories
entity_id = parts[1] # ID сущности
photo_id = parts[2] # ID фото
# Определяем размер в имени файла
filename = parts[-1] if parts else os.path.basename(path_str)
# Проверяем, является ли это новой структурой
if filename in ['original.jpg', 'large.webp', 'medium.webp', 'thumb.webp']:
# Это новая структура, заменяем только размер
ext_map = {
'original': 'jpg',
'large': 'webp',
'medium': 'webp',
'thumbnail': 'webp',
}
target_ext = ext_map.get(size, 'jpg')
# Переименовываем thumbnail в thumb
final_size_name = 'thumb' if size == 'thumbnail' else size
# Создаем путь в новой структуре
new_path = f"{base_path}/{entity_id}/{photo_id}/{final_size_name}.{target_ext}"
# Проверяем существование файла
if default_storage.exists(new_path):
return f"{settings.MEDIA_URL}{new_path}"
# Если файл не найден, пробуем с другим расширением
# Определяем расширение из конфигурации
format_config = ImageService._get_format_config(size)
image_format = format_config.get('format', 'JPEG')
ext_map_config = {
'JPEG': 'jpg',
'WEBP': 'webp',
'PNG': 'png',
}
target_ext = ext_map_config.get(image_format, 'jpg')
final_size_name = 'thumb' if size == 'thumbnail' else size
fallback_path = f"{base_path}/{entity_id}/{photo_id}/{final_size_name}.{target_ext}"
if default_storage.exists(fallback_path):
return f"{settings.MEDIA_URL}{fallback_path}"
return f"{settings.MEDIA_URL}{path_str}"
# Старая структура для совместимости
filename = os.path.basename(path_str)
# Определяем базовый путь (products, kits, categories)
parts = path_str.split('/')
if len(parts) > 0:
base_path = parts[0]
else:
base_path = 'products'
# Проверяем новый формат имени файла с расширением
# Проверяем старый формат имени файла с расширением
# Поддерживаем jpg, webp, png расширения
if filename.endswith(('.jpg', '.webp', '.png')):
# Определяем расширение файла
@@ -97,7 +149,7 @@ class ImageService:
if len(parts_of_name) == 2:
base_filename, file_size_key = parts_of_name
# Это новый формат с явным указанием размера в имени
# Это старый формат с явным указанием размера в имени
# Получаем расширение для целевого размера
target_ext = ImageService._get_file_extension(size)
@@ -123,7 +175,6 @@ class ImageService:
# Если ничего не найдено, возвращаем путь с новым расширением (браузер покажет ошибку)
return f"{settings.MEDIA_URL}{new_path_primary}"
# Иначе оставляем как есть
# Строим новый путь (для старых файлов без новой структуры)
size_folders = ImageService._get_size_folders()