Исправление отображения фото в POS и улучшение обработки изображений

- Исправлен POS для использования миниатюр вместо оригиналов для быстрой загрузки
- Убран fallback на оригиналы - показываем миниатюру или ничего (лучше видно ошибки)
- Исправлен ImageService - возвращает пустую строку если миниатюра обработанного файла не найдена
- Исправлена ошибка JavaScript при массовом удалении фото (insertAdjacentElement на null)
- Добавлен контейнер photos-messages-container для надежного отображения сообщений
- Улучшено логирование ImageService для отладки путей к файлам
- Добавлена проверка exists() с детальным логированием в TenantAwareFileSystemStorage
This commit is contained in:
2025-12-21 19:52:55 +03:00
parent 812ecb53e6
commit bb821f9ef4
4 changed files with 76 additions and 12 deletions

View File

@@ -3,9 +3,12 @@
Используется в шаблонах и представлениях для удобного доступа к разным версиям.
"""
import os
import logging
from django.conf import settings
from django.core.files.storage import default_storage
logger = logging.getLogger(__name__)
class ImageService:
"""
@@ -63,7 +66,7 @@ class ImageService:
По умолчанию 'medium'
Returns:
str: URL изображения или пустая строка если нет файла
str: URL изображения нужного размера, или оригинал если размер не найден
"""
if not original_image_path:
return ''
@@ -80,6 +83,10 @@ class ImageService:
if 'temp' in parts:
return default_storage.url(path_str)
# Если запрашивается оригинал, возвращаем его напрямую
if size == 'original':
return default_storage.url(path_str)
# Извлекаем base_path, entity_id, photo_id из пути
base_path = parts[0] # products, kits, categories
entity_id = parts[1] # ID сущности
@@ -98,10 +105,25 @@ class ImageService:
# Используем default_storage.url() для корректной работы с TenantAwareFileSystemStorage
# Это гарантирует что URL будет содержать tenant_id если необходимо
return default_storage.url(file_path)
# Проверяем существование файла - если не найден, возвращаем пустую строку
# (для обработанных файлов миниатюра должна существовать)
if default_storage.exists(file_path):
url = default_storage.url(file_path)
logger.debug(f"[ImageService] Returning {size} URL: {file_path} -> {url}")
return url
else:
# Файл нужного размера не найден - возвращаем пустую строку
# (файл обработан, но миниатюра не создана - это ошибка)
logger.warning(f"[ImageService] {size} file not found: {file_path}, file should be processed")
return ''
except Exception:
return ''
except Exception as e:
# В случае ошибки возвращаем оригинал
logger.warning(f"[ImageService] Error getting {size} URL: {e}, using original as fallback")
try:
return default_storage.url(str(original_image_path))
except Exception:
return ''
@staticmethod
def get_thumbnail_url(original_image_path):