Добавлена система фильтрации клиентов с универсальным поиском
- Реализован универсальный поиск по имени, email и телефону в одной строке - Добавлен счетчик общего количества клиентов - Поиск работает по нажатию Enter или кнопке 'Поиск' - Удалены неиспользуемые фильтры django-filter - Упрощен интерфейс списка клиентов - Добавлена кнопка 'Очистить' для сброса поиска
This commit is contained in:
67
myproject/customers/management/commands/analyze_import.py
Normal file
67
myproject/customers/management/commands/analyze_import.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Анализ проблемных строк в XLSX файле для импорта.
|
||||
Показывает первые 30 строк с проблемными телефонами.
|
||||
"""
|
||||
from django.core.management.base import BaseCommand
|
||||
import os
|
||||
|
||||
try:
|
||||
from openpyxl import load_workbook
|
||||
except ImportError:
|
||||
load_workbook = None
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Анализ проблемных данных в файле импорта'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('file_path', type=str, help='Путь к файлу для анализа')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
file_path = options['file_path']
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
self.stdout.write(self.style.ERROR(f'Файл не найден: {file_path}'))
|
||||
return
|
||||
|
||||
if load_workbook is None:
|
||||
self.stdout.write(self.style.ERROR('Установите openpyxl'))
|
||||
return
|
||||
|
||||
wb = load_workbook(file_path, read_only=True, data_only=True)
|
||||
ws = wb.active
|
||||
|
||||
headers = []
|
||||
rows_data = []
|
||||
|
||||
first_row = True
|
||||
for idx, row in enumerate(ws.iter_rows(values_only=True), start=1):
|
||||
if first_row:
|
||||
headers = [str(v).strip() if v is not None else "" for v in row]
|
||||
self.stdout.write(f"Заголовки: {headers}\n")
|
||||
first_row = False
|
||||
continue
|
||||
|
||||
if not any(row):
|
||||
continue
|
||||
|
||||
row_dict = {}
|
||||
for col_idx, value in enumerate(row):
|
||||
if col_idx < len(headers):
|
||||
header = headers[col_idx]
|
||||
row_dict[header] = value
|
||||
|
||||
rows_data.append((idx, row_dict))
|
||||
|
||||
# Показываем первые 30 строк
|
||||
self.stdout.write(self.style.SUCCESS(f"\nПервые 30 строк данных:\n"))
|
||||
self.stdout.write("=" * 100)
|
||||
|
||||
for row_num, data in rows_data[:30]:
|
||||
self.stdout.write(f"\n[Строка {row_num}]")
|
||||
for key, val in data.items():
|
||||
if val:
|
||||
self.stdout.write(f" {key}: {val}")
|
||||
self.stdout.write("-" * 100)
|
||||
|
||||
self.stdout.write(f"\n\nВсего строк с данными: {len(rows_data)}")
|
||||
Reference in New Issue
Block a user