""" Утилиты для работы с фотографиями товаров, комплектов и категорий. """ import os from django.db import models def validate_photo(photo): """ Валидация загружаемого фото. Возвращает (True, None) если валидно, или (False, error_message) если ошибка. """ max_size = 5 * 1024 * 1024 # 5MB allowed_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'] if photo.size > max_size: return False, f'Размер файла {photo.name} превышает 5MB.' ext = os.path.splitext(photo.name)[1].lower() if ext not in allowed_extensions: return False, f'Формат файла {ext} не поддерживается. Разрешены: {", ".join(allowed_extensions)}' return True, None def handle_photos(request, parent_obj, photo_model, parent_field_name): """ Универсальная обработка загружаемых фотографий. Args: request: HTTP request с FILES parent_obj: Родительский объект (Product, ProductKit или ProductCategory) photo_model: Модель фотографии (ProductPhoto, ProductKitPhoto, ProductCategoryPhoto) parent_field_name: Имя поля связи в модели фото ('product', 'kit', 'category') Returns: Список сообщений об ошибках (пустой список если все ок). """ errors = [] warnings = [] photos = request.FILES.getlist('photos') if not photos: return errors # МАКСИМУМ 10 ФОТО - сохраняем первые 10, остальные отклоняем MAX_PHOTOS = 10 if len(photos) > MAX_PHOTOS: warnings.append(f'Загружено {len(photos)} фото, но обработано только первые {MAX_PHOTOS}. ' f'Максимум {MAX_PHOTOS} фото на товар.') photos = photos[:MAX_PHOTOS] # Получаем максимальный order для этого родительского объекта filter_kwargs = {parent_field_name: parent_obj} max_order = photo_model.objects.filter(**filter_kwargs).aggregate( models.Max('order') )['order__max'] # Если фото нет, начинаем с 0, иначе с max_order + 1 next_order = 0 if max_order is None else max_order + 1 # Валидация и сохранение фото for photo in photos: is_valid, error_msg = validate_photo(photo) if not is_valid: errors.append(error_msg) else: # Создаем фото с правильной связью create_kwargs = { parent_field_name: parent_obj, 'image': photo, 'order': next_order } photo_model.objects.create(**create_kwargs) next_order += 1 # Добавляем warnings в errors для отображения пользователю errors.extend(warnings) return errors