Добавить функционал массового изменения категорий товаров

- Добавлен UI для пакетного выбора товаров с чекбоксами
- Реализована возможность выбора всех товаров на странице
- Реализована возможность выбора всех отфильтрованных товаров
- Добавлено модальное окно для массового управления категориями
- Добавлены API эндпоинты: get_filtered_items_ids, bulk_update_categories
- Реализованы три режима работы с категориями: добавление, замена, очистка
- Добавлен селектор количества элементов на странице (20/50/100)
- Улучшена информативность о количестве выбранных элементов
This commit is contained in:
2026-01-07 09:15:53 +03:00
parent d5c1ed1e4b
commit 161f65e6c3
6 changed files with 1297 additions and 13 deletions

View File

@@ -97,13 +97,6 @@ class ProductListView(LoginRequiredMixin, ManagerOwnerRequiredMixin, ListView):
'icon': 'box-seam'
})
action_buttons.append({
'url': reverse_lazy('products:productkit-list'),
'text': 'К списку комплектов',
'class': 'btn-outline-secondary',
'icon': 'list'
})
context['action_buttons'] = action_buttons
return context
@@ -265,6 +258,22 @@ class CombinedProductListView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Lis
context_object_name = 'items'
paginate_by = 20
def get_paginate_by(self, queryset):
"""
Динамическое определение количества элементов на странице.
Читает параметр per_page из GET-запроса.
"""
per_page = self.request.GET.get('per_page', '20')
try:
per_page_int = int(per_page)
# Разрешаем только значения 20, 50, 100
if per_page_int in [20, 50, 100]:
return per_page_int
except (ValueError, TypeError):
pass
# По умолчанию возвращаем 20
return 20
def get_queryset(self):
# Получаем фильтр по типу
type_filter = self.request.GET.get('type', 'all')
@@ -377,6 +386,7 @@ class CombinedProductListView(LoginRequiredMixin, ManagerOwnerRequiredMixin, Lis
'type': self.request.GET.get('type', 'all'),
'in_stock': self.request.GET.get('in_stock', ''),
'tags': [int(tag) for tag in self.request.GET.getlist('tags') if tag.isdigit()],
'per_page': self.request.GET.get('per_page', '20'),
}
}