diff --git a/myproject/products/templates/products/product_form.html b/myproject/products/templates/products/product_form.html
index 46014ea..126040e 100644
--- a/myproject/products/templates/products/product_form.html
+++ b/myproject/products/templates/products/product_form.html
@@ -182,11 +182,23 @@
{% if object and product_photos %}
-
Текущие фотографии ({{ photos_count }})
-
+
+
Текущие фотографии ({{ photos_count }})
+
+
+
{% for photo in product_photos %}
-
-
+
+
+
+
+
+
+
+
+
+
{% endif %}
diff --git a/myproject/products/urls.py b/myproject/products/urls.py
index c120ad1..e7f2d91 100644
--- a/myproject/products/urls.py
+++ b/myproject/products/urls.py
@@ -24,6 +24,7 @@ urlpatterns = [
path('product/photo/
/set-main/', views.product_photo_set_main, name='product-photo-set-main'),
path('product/photo//move-up/', views.product_photo_move_up, name='product-photo-move-up'),
path('product/photo//move-down/', views.product_photo_move_down, name='product-photo-move-down'),
+ path('product/photos/delete-bulk/', views.product_photos_delete_bulk, name='product-photos-delete-bulk'),
# CRUD URLs for ProductKit (комплекты/букеты)
path('kit/create/', views.ProductKitCreateView.as_view(), name='productkit-create'),
diff --git a/myproject/products/views/__init__.py b/myproject/products/views/__init__.py
index 25d1285..a49dcbe 100644
--- a/myproject/products/views/__init__.py
+++ b/myproject/products/views/__init__.py
@@ -12,6 +12,7 @@ from .photo_management import (
product_photo_set_main,
product_photo_move_up,
product_photo_move_down,
+ product_photos_delete_bulk,
)
# Управление фотографиями (ProductKit)
@@ -105,6 +106,7 @@ __all__ = [
'product_photo_set_main',
'product_photo_move_up',
'product_photo_move_down',
+ 'product_photos_delete_bulk',
# Управление фотографиями ProductKit
'productkit_photo_delete',
diff --git a/myproject/products/views/photo_management.py b/myproject/products/views/photo_management.py
index a468e53..1b88e5c 100644
--- a/myproject/products/views/photo_management.py
+++ b/myproject/products/views/photo_management.py
@@ -2,8 +2,13 @@
Универсальные функции для управления фотографиями товаров, комплектов и категорий.
Устраняет дублирование кода для операций: delete, set_main, move_up, move_down.
"""
+import json
from django.shortcuts import get_object_or_404, redirect
from django.contrib import messages
+from django.http import JsonResponse
+from django.views.decorators.http import require_http_methods
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.mixins import PermissionRequiredMixin
from ..models import ProductPhoto, ProductKitPhoto, ProductCategoryPhoto
@@ -308,3 +313,71 @@ def category_photo_move_down(request, pk):
parent_attr='category',
permission='products.change_productcategory'
)
+
+
+# ====================================
+# AJAX Endpoints для массового удаления
+# ====================================
+
+@require_http_methods(["POST"])
+@login_required
+def product_photos_delete_bulk(request):
+ """
+ AJAX endpoint для массового удаления фотографий товара.
+
+ Ожидает JSON: {photo_ids: [1, 2, 3]}
+ Возвращает JSON: {success: true, deleted: 3} или {success: false, error: "..."}
+ """
+ # Проверка прав доступа
+ if not request.user.has_perm('products.change_product'):
+ return JsonResponse({
+ 'success': False,
+ 'error': 'У вас нет прав для удаления фотографий'
+ }, status=403)
+
+ try:
+ # Получаем список photo_ids из JSON тела запроса
+ data = json.loads(request.body)
+ photo_ids = data.get('photo_ids', [])
+
+ if not photo_ids or not isinstance(photo_ids, list):
+ return JsonResponse({
+ 'success': False,
+ 'error': 'Неверный формат: требуется список photo_ids'
+ }, status=400)
+
+ # Удаляем фотографии
+ deleted_count = 0
+ for photo_id in photo_ids:
+ try:
+ photo = ProductPhoto.objects.get(pk=photo_id)
+ photo.delete() # Это вызовет ImageProcessor.delete_all_versions()
+ deleted_count += 1
+ except ProductPhoto.DoesNotExist:
+ # Если фото не найдена, просто пропускаем
+ continue
+ except Exception as e:
+ # Логируем ошибку но продолжаем удаление остальных
+ import logging
+ logger = logging.getLogger(__name__)
+ logger.error(f"Error deleting photo {photo_id}: {str(e)}", exc_info=True)
+ continue
+
+ return JsonResponse({
+ 'success': True,
+ 'deleted': deleted_count
+ })
+
+ except json.JSONDecodeError:
+ return JsonResponse({
+ 'success': False,
+ 'error': 'Неверный JSON формат'
+ }, status=400)
+ except Exception as e:
+ import logging
+ logger = logging.getLogger(__name__)
+ logger.error(f"Bulk photo deletion error: {str(e)}", exc_info=True)
+ return JsonResponse({
+ 'success': False,
+ 'error': f'Ошибка сервера: {str(e)}'
+ }, status=500)