Исправил импорт данных с привязкой спутников
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -34,3 +34,4 @@ tiles
|
|||||||
# docker-*
|
# docker-*
|
||||||
maplibre-gl-js-5.10.0.zip
|
maplibre-gl-js-5.10.0.zip
|
||||||
cert.pem
|
cert.pem
|
||||||
|
templ.json
|
||||||
@@ -214,12 +214,15 @@ class CSVImportTestCase(TestCase):
|
|||||||
3;Signal3 V;56.8389;60.6057;0;01.01.2024 12:10:00;Test Satellite;12345;11540.7;36.0;1;good;Mirror1;Mirror2;"""
|
3;Signal3 V;56.8389;60.6057;0;01.01.2024 12:10:00;Test Satellite;12345;11540.7;36.0;1;good;Mirror1;Mirror2;"""
|
||||||
|
|
||||||
# Выполняем импорт
|
# Выполняем импорт
|
||||||
sources_created = get_points_from_csv(csv_content, self.custom_user)
|
result = get_points_from_csv(csv_content, self.custom_user)
|
||||||
|
|
||||||
# Проверяем результаты
|
# Проверяем результаты
|
||||||
# Первые две точки близко (Москва), третья далеко (Екатеринбург)
|
# Первые две точки близко (Москва), третья далеко (Екатеринбург)
|
||||||
# Должно быть создано 2 источника
|
# Должно быть создано 2 источника
|
||||||
self.assertEqual(sources_created, 2)
|
self.assertEqual(result['new_sources'], 2)
|
||||||
|
self.assertEqual(result['added'], 3)
|
||||||
|
self.assertEqual(result['skipped'], 0)
|
||||||
|
self.assertEqual(len(result['errors']), 0)
|
||||||
self.assertEqual(Source.objects.count(), 2)
|
self.assertEqual(Source.objects.count(), 2)
|
||||||
self.assertEqual(ObjItem.objects.count(), 3)
|
self.assertEqual(ObjItem.objects.count(), 3)
|
||||||
|
|
||||||
@@ -237,8 +240,8 @@ class CSVImportTestCase(TestCase):
|
|||||||
csv_content_1 = """1;Signal1 V;55.7558;37.6173;0;01.01.2024 12:00:00;Test Satellite;12345;11500.5;36.0;1;good;Mirror1;Mirror2;
|
csv_content_1 = """1;Signal1 V;55.7558;37.6173;0;01.01.2024 12:00:00;Test Satellite;12345;11500.5;36.0;1;good;Mirror1;Mirror2;
|
||||||
2;Signal2 H;55.7560;37.6175;0;01.01.2024 12:05:00;Test Satellite;12345;11520.3;36.0;1;good;Mirror1;Mirror2;"""
|
2;Signal2 H;55.7560;37.6175;0;01.01.2024 12:05:00;Test Satellite;12345;11520.3;36.0;1;good;Mirror1;Mirror2;"""
|
||||||
|
|
||||||
sources_created_1 = get_points_from_csv(csv_content_1, self.custom_user)
|
result_1 = get_points_from_csv(csv_content_1, self.custom_user)
|
||||||
self.assertEqual(sources_created_1, 1)
|
self.assertEqual(result_1['new_sources'], 1)
|
||||||
initial_sources_count = Source.objects.count()
|
initial_sources_count = Source.objects.count()
|
||||||
initial_objitems_count = ObjItem.objects.count()
|
initial_objitems_count = ObjItem.objects.count()
|
||||||
|
|
||||||
@@ -248,11 +251,12 @@ class CSVImportTestCase(TestCase):
|
|||||||
csv_content_2 = """3;Signal3 V;55.7562;37.6177;0;01.01.2024 12:10:00;Test Satellite;12345;11540.7;36.0;1;good;Mirror1;Mirror2;
|
csv_content_2 = """3;Signal3 V;55.7562;37.6177;0;01.01.2024 12:10:00;Test Satellite;12345;11540.7;36.0;1;good;Mirror1;Mirror2;
|
||||||
4;Signal4 H;56.8389;60.6057;0;01.01.2024 12:15:00;Test Satellite;12345;11560.2;36.0;1;good;Mirror1;Mirror2;"""
|
4;Signal4 H;56.8389;60.6057;0;01.01.2024 12:15:00;Test Satellite;12345;11560.2;36.0;1;good;Mirror1;Mirror2;"""
|
||||||
|
|
||||||
sources_created_2 = get_points_from_csv(csv_content_2, self.custom_user)
|
result_2 = get_points_from_csv(csv_content_2, self.custom_user)
|
||||||
|
|
||||||
# Проверяем результаты
|
# Проверяем результаты
|
||||||
# Должен быть создан 1 новый источник (для точки 4)
|
# Должен быть создан 1 новый источник (для точки 4)
|
||||||
self.assertEqual(sources_created_2, 1)
|
self.assertEqual(result_2['new_sources'], 1)
|
||||||
|
self.assertEqual(result_2['added'], 2)
|
||||||
self.assertEqual(Source.objects.count(), initial_sources_count + 1)
|
self.assertEqual(Source.objects.count(), initial_sources_count + 1)
|
||||||
self.assertEqual(ObjItem.objects.count(), initial_objitems_count + 2)
|
self.assertEqual(ObjItem.objects.count(), initial_objitems_count + 2)
|
||||||
|
|
||||||
@@ -276,10 +280,12 @@ class CSVImportTestCase(TestCase):
|
|||||||
# Второй импорт - та же точка (дубликат)
|
# Второй импорт - та же точка (дубликат)
|
||||||
csv_content_2 = """1;Signal1 V;55.7558;37.6173;0;01.01.2024 12:00:00;Test Satellite;12345;11500.5;36.0;1;good;Mirror1;Mirror2;"""
|
csv_content_2 = """1;Signal1 V;55.7558;37.6173;0;01.01.2024 12:00:00;Test Satellite;12345;11500.5;36.0;1;good;Mirror1;Mirror2;"""
|
||||||
|
|
||||||
sources_created = get_points_from_csv(csv_content_2, self.custom_user)
|
result = get_points_from_csv(csv_content_2, self.custom_user)
|
||||||
|
|
||||||
# Проверяем, что дубликат пропущен
|
# Проверяем, что дубликат пропущен
|
||||||
self.assertEqual(sources_created, 0)
|
self.assertEqual(result['new_sources'], 0)
|
||||||
|
self.assertEqual(result['added'], 0)
|
||||||
|
self.assertEqual(result['skipped'], 1)
|
||||||
self.assertEqual(Source.objects.count(), initial_sources_count)
|
self.assertEqual(Source.objects.count(), initial_sources_count)
|
||||||
self.assertEqual(ObjItem.objects.count(), initial_objitems_count)
|
self.assertEqual(ObjItem.objects.count(), initial_objitems_count)
|
||||||
|
|
||||||
@@ -304,10 +310,12 @@ class CSVImportTestCase(TestCase):
|
|||||||
4;Signal4 H;56.8389;60.6057;0;01.01.2024 12:15:00;Test Satellite;12345;11560.2;36.0;1;good;Mirror1;Mirror2;
|
4;Signal4 H;56.8389;60.6057;0;01.01.2024 12:15:00;Test Satellite;12345;11560.2;36.0;1;good;Mirror1;Mirror2;
|
||||||
5;Signal5 V;56.8391;60.6059;0;01.01.2024 12:20:00;Test Satellite;12345;11580.8;36.0;1;good;Mirror1;Mirror2;"""
|
5;Signal5 V;56.8391;60.6059;0;01.01.2024 12:20:00;Test Satellite;12345;11580.8;36.0;1;good;Mirror1;Mirror2;"""
|
||||||
|
|
||||||
sources_created = get_points_from_csv(csv_content_2, self.custom_user)
|
result = get_points_from_csv(csv_content_2, self.custom_user)
|
||||||
|
|
||||||
# Проверяем результаты
|
# Проверяем результаты
|
||||||
self.assertEqual(sources_created, 1) # Только для Екатеринбурга
|
self.assertEqual(result['new_sources'], 1) # Только для Екатеринбурга
|
||||||
|
self.assertEqual(result['added'], 3) # Точки 3, 4, 5
|
||||||
|
self.assertEqual(result['skipped'], 1) # Точка 1 (дубликат)
|
||||||
self.assertEqual(Source.objects.count(), 2) # Москва + Екатеринбург
|
self.assertEqual(Source.objects.count(), 2) # Москва + Екатеринбург
|
||||||
self.assertEqual(ObjItem.objects.count(), 5) # 2 начальных + 3 новых (дубликат пропущен)
|
self.assertEqual(ObjItem.objects.count(), 5) # 2 начальных + 3 новых (дубликат пропущен)
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,72 @@ MINIMUM_BANDWIDTH_MHZ = 0.08
|
|||||||
|
|
||||||
RANGE_DISTANCE = 56
|
RANGE_DISTANCE = 56
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Вспомогательные функции для работы со спутниками
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
class SatelliteNotFoundError(Exception):
|
||||||
|
"""Исключение, возникающее когда спутник не найден в базе данных."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_satellite_by_norad(norad_id: int) -> Satellite:
|
||||||
|
"""
|
||||||
|
Получает спутник по NORAD ID с обработкой ошибок.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
norad_id: NORAD ID спутника
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Satellite: объект спутника
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
SatelliteNotFoundError: если спутник не найден
|
||||||
|
ValueError: если norad_id некорректен
|
||||||
|
"""
|
||||||
|
if not norad_id or norad_id == -1:
|
||||||
|
raise ValueError(f"Некорректный NORAD ID: {norad_id}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return Satellite.objects.get(norad=norad_id)
|
||||||
|
except Satellite.DoesNotExist:
|
||||||
|
raise SatelliteNotFoundError(
|
||||||
|
f"Спутник с NORAD ID {norad_id} не найден в базе данных. "
|
||||||
|
f"Добавьте спутник в справочник перед импортом данных."
|
||||||
|
)
|
||||||
|
except Satellite.MultipleObjectsReturned:
|
||||||
|
# Если по какой-то причине есть дубликаты, берем первый
|
||||||
|
return Satellite.objects.filter(norad=norad_id).first()
|
||||||
|
|
||||||
|
|
||||||
|
def get_satellite_by_name(name: str) -> Satellite:
|
||||||
|
"""
|
||||||
|
Получает спутник по имени с обработкой ошибок.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: имя спутника
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Satellite: объект спутника
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
SatelliteNotFoundError: если спутник не найден
|
||||||
|
"""
|
||||||
|
if not name or name.strip() == "-":
|
||||||
|
raise ValueError(f"Некорректное имя спутника: {name}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
return Satellite.objects.get(name=name.strip())
|
||||||
|
except Satellite.DoesNotExist:
|
||||||
|
raise SatelliteNotFoundError(
|
||||||
|
f"Спутник '{name}' не найден в базе данных. "
|
||||||
|
f"Добавьте спутник в справочник перед импортом данных."
|
||||||
|
)
|
||||||
|
except Satellite.MultipleObjectsReturned:
|
||||||
|
# Если есть дубликаты по имени, берем первый
|
||||||
|
return Satellite.objects.filter(name=name.strip()).first()
|
||||||
|
|
||||||
def get_all_constants():
|
def get_all_constants():
|
||||||
sats = [sat.name for sat in Satellite.objects.all()]
|
sats = [sat.name for sat in Satellite.objects.all()]
|
||||||
standards = [sat.name for sat in Standard.objects.all()]
|
standards = [sat.name for sat in Standard.objects.all()]
|
||||||
@@ -307,7 +373,12 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
|||||||
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: количество созданных Source (или 0 если is_automatic=True)
|
dict: словарь с результатами импорта {
|
||||||
|
'new_sources': количество созданных Source,
|
||||||
|
'added': количество добавленных точек,
|
||||||
|
'skipped': количество пропущенных дубликатов,
|
||||||
|
'errors': список ошибок
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
df.rename(columns={"Модуляция ": "Модуляция"}, inplace=True)
|
df.rename(columns={"Модуляция ": "Модуляция"}, inplace=True)
|
||||||
@@ -321,6 +392,7 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
|||||||
new_sources_count = 0
|
new_sources_count = 0
|
||||||
added_count = 0
|
added_count = 0
|
||||||
skipped_count = 0
|
skipped_count = 0
|
||||||
|
errors = []
|
||||||
|
|
||||||
# Словарь для кэширования Source в рамках текущего импорта
|
# Словарь для кэширования Source в рамках текущего импорта
|
||||||
# Ключ: (имя источника, id Source), Значение: объект Source
|
# Ключ: (имя источника, id Source), Значение: объект Source
|
||||||
@@ -391,13 +463,21 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
|||||||
added_count += 1
|
added_count += 1
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||||
print(f"Ошибка при обработке строки {idx}: {e}")
|
print(f"Ошибка при обработке строки {idx}: {e}")
|
||||||
|
errors.append(error_msg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
||||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов")
|
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов, "
|
||||||
|
f"ошибок: {len(errors)}")
|
||||||
|
|
||||||
return new_sources_count
|
return {
|
||||||
|
'new_sources': new_sources_count,
|
||||||
|
'added': added_count,
|
||||||
|
'skipped': skipped_count,
|
||||||
|
'errors': errors
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _create_objitem_from_row(row, sat, source, user_to_use, consts, is_automatic=False):
|
def _create_objitem_from_row(row, sat, source, user_to_use, consts, is_automatic=False):
|
||||||
@@ -574,6 +654,11 @@ def _create_objitem_from_row(row, sat, source, user_to_use, consts, is_automatic
|
|||||||
|
|
||||||
|
|
||||||
def add_satellite_list():
|
def add_satellite_list():
|
||||||
|
"""
|
||||||
|
Добавляет список спутников в базу данных (если их еще нет).
|
||||||
|
|
||||||
|
Примечание: Эта функция устарела. Используйте админ-панель для добавления спутников.
|
||||||
|
"""
|
||||||
sats = [
|
sats = [
|
||||||
"AZERSPACE 2",
|
"AZERSPACE 2",
|
||||||
"Amos 4",
|
"Amos 4",
|
||||||
@@ -673,7 +758,12 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
|||||||
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: количество созданных Source (или 0 если is_automatic=True)
|
dict: словарь с результатами импорта {
|
||||||
|
'new_sources': количество созданных Source,
|
||||||
|
'added': количество добавленных точек,
|
||||||
|
'skipped': количество пропущенных дубликатов,
|
||||||
|
'errors': список ошибок
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
df = pd.read_csv(
|
df = pd.read_csv(
|
||||||
io.StringIO(file_content),
|
io.StringIO(file_content),
|
||||||
@@ -711,6 +801,7 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
|||||||
new_sources_count = 0
|
new_sources_count = 0
|
||||||
added_count = 0
|
added_count = 0
|
||||||
skipped_count = 0
|
skipped_count = 0
|
||||||
|
errors = []
|
||||||
|
|
||||||
# Словарь для кэширования Source в рамках текущего импорта
|
# Словарь для кэширования Source в рамках текущего импорта
|
||||||
# Ключ: (имя источника, имя спутника, id Source), Значение: объект Source
|
# Ключ: (имя источника, имя спутника, id Source), Значение: объект Source
|
||||||
@@ -733,14 +824,15 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
|||||||
skipped_count += 1
|
skipped_count += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Получаем или создаем объект спутника
|
# Получаем объект спутника по NORAD ID
|
||||||
# sat_obj, _ = Satellite.objects.get_or_create(
|
try:
|
||||||
# name=sat_name, defaults={"norad": row["norad_id"]}
|
sat_obj = get_satellite_by_norad(row["norad_id"])
|
||||||
# )
|
except (SatelliteNotFoundError, ValueError) as e:
|
||||||
|
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||||
|
print(error_msg)
|
||||||
|
errors.append(error_msg)
|
||||||
|
continue
|
||||||
|
|
||||||
sat_obj, _ = Satellite.objects.get_or_create(
|
|
||||||
norad=row["norad_id"], defaults={"name": sat_name}
|
|
||||||
)
|
|
||||||
source = None
|
source = None
|
||||||
|
|
||||||
# Если is_automatic=False, работаем с Source
|
# Если is_automatic=False, работаем с Source
|
||||||
@@ -785,13 +877,21 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
|||||||
added_count += 1
|
added_count += 1
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||||
print(f"Ошибка при обработке строки {idx}: {e}")
|
print(f"Ошибка при обработке строки {idx}: {e}")
|
||||||
|
errors.append(error_msg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
||||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов")
|
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов, "
|
||||||
|
f"ошибок: {len(errors)}")
|
||||||
|
|
||||||
return new_sources_count
|
return {
|
||||||
|
'new_sources': new_sources_count,
|
||||||
|
'added': added_count,
|
||||||
|
'skipped': skipped_count,
|
||||||
|
'errors': errors
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _is_duplicate_by_coords_and_time(coord_tuple, timestamp, tolerance_km=0.001):
|
def _is_duplicate_by_coords_and_time(coord_tuple, timestamp, tolerance_km=0.001):
|
||||||
@@ -923,9 +1023,12 @@ def _create_objitem_from_csv_row(row, source, user_to_use, is_automatic=False):
|
|||||||
pol = "-"
|
pol = "-"
|
||||||
|
|
||||||
pol_obj, _ = Polarization.objects.get_or_create(name=pol)
|
pol_obj, _ = Polarization.objects.get_or_create(name=pol)
|
||||||
sat_obj, _ = Satellite.objects.get_or_create(
|
|
||||||
name=row["sat"], defaults={"norad": row["norad_id"]}
|
# Получаем объект спутника по NORAD ID
|
||||||
)
|
try:
|
||||||
|
sat_obj = get_satellite_by_norad(row["norad_id"])
|
||||||
|
except (SatelliteNotFoundError, ValueError) as e:
|
||||||
|
raise Exception(f"Не удалось получить спутник: {str(e)}")
|
||||||
|
|
||||||
# Ищем данные в TechAnalyze
|
# Ищем данные в TechAnalyze
|
||||||
tech_data = _find_tech_analyze_data(row["obj"], sat_obj)
|
tech_data = _find_tech_analyze_data(row["obj"], sat_obj)
|
||||||
|
|||||||
@@ -88,14 +88,25 @@ class LoadExcelDataView(LoginRequiredMixin, FormMessageMixin, FormView):
|
|||||||
df = df.head(number)
|
df = df.head(number)
|
||||||
result = fill_data_from_df(df, selected_sat, self.request.user.customuser, is_automatic)
|
result = fill_data_from_df(df, selected_sat, self.request.user.customuser, is_automatic)
|
||||||
|
|
||||||
|
# Формируем сообщение об успехе
|
||||||
if is_automatic:
|
if is_automatic:
|
||||||
messages.success(
|
success_msg = f"Данные успешно загружены как автоматические! Добавлено точек: {result['added']}"
|
||||||
self.request, f"Данные успешно загружены как автоматические! Добавлено точек: {len(df)}"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
messages.success(
|
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
|
||||||
self.request, f"Данные успешно загружены! Создано источников: {result}"
|
|
||||||
|
if result['skipped'] > 0:
|
||||||
|
success_msg += f", пропущено дубликатов: {result['skipped']}"
|
||||||
|
|
||||||
|
messages.success(self.request, success_msg)
|
||||||
|
|
||||||
|
# Показываем ошибки, если они есть
|
||||||
|
if result['errors']:
|
||||||
|
error_count = len(result['errors'])
|
||||||
|
messages.warning(
|
||||||
|
self.request,
|
||||||
|
f"Обнаружено ошибок: {error_count}. Первые ошибки: " + "; ".join(result['errors'][:5])
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
||||||
|
|
||||||
@@ -124,10 +135,25 @@ class LoadCsvDataView(LoginRequiredMixin, FormMessageMixin, FormView):
|
|||||||
|
|
||||||
result = get_points_from_csv(content, self.request.user.customuser, is_automatic)
|
result = get_points_from_csv(content, self.request.user.customuser, is_automatic)
|
||||||
|
|
||||||
|
# Формируем сообщение об успехе
|
||||||
if is_automatic:
|
if is_automatic:
|
||||||
messages.success(self.request, "Данные успешно загружены как автоматические!")
|
success_msg = f"Данные успешно загружены как автоматические! Добавлено точек: {result['added']}"
|
||||||
else:
|
else:
|
||||||
messages.success(self.request, f"Данные успешно загружены! Создано источников: {result}")
|
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
|
||||||
|
|
||||||
|
if result['skipped'] > 0:
|
||||||
|
success_msg += f", пропущено дубликатов: {result['skipped']}"
|
||||||
|
|
||||||
|
messages.success(self.request, success_msg)
|
||||||
|
|
||||||
|
# Показываем ошибки, если они есть
|
||||||
|
if result['errors']:
|
||||||
|
error_count = len(result['errors'])
|
||||||
|
messages.warning(
|
||||||
|
self.request,
|
||||||
|
f"Обнаружено ошибок: {error_count}. Первые ошибки: " + "; ".join(result['errors'][:5])
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
||||||
return redirect("mainapp:load_csv_data")
|
return redirect("mainapp:load_csv_data")
|
||||||
|
|||||||
@@ -113,9 +113,17 @@ class LoadExcelDataView(LoginRequiredMixin, FormMessageMixin, FormView):
|
|||||||
df = df.head(number)
|
df = df.head(number)
|
||||||
result = fill_data_from_df(df, selected_sat, self.request.user.customuser)
|
result = fill_data_from_df(df, selected_sat, self.request.user.customuser)
|
||||||
|
|
||||||
messages.success(
|
# Обработка нового формата результата
|
||||||
self.request, f"Данные успешно загружены! Обработано строк: {result}"
|
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
|
||||||
)
|
if result['skipped'] > 0:
|
||||||
|
success_msg += f", пропущено дубликатов: {result['skipped']}"
|
||||||
|
messages.success(self.request, success_msg)
|
||||||
|
|
||||||
|
if result['errors']:
|
||||||
|
messages.warning(
|
||||||
|
self.request,
|
||||||
|
f"Обнаружено ошибок: {len(result['errors'])}. Первые ошибки: " + "; ".join(result['errors'][:5])
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
||||||
|
|
||||||
@@ -180,7 +188,19 @@ class LoadCsvDataView(LoginRequiredMixin, FormMessageMixin, FormView):
|
|||||||
if isinstance(content, bytes):
|
if isinstance(content, bytes):
|
||||||
content = content.decode("utf-8")
|
content = content.decode("utf-8")
|
||||||
|
|
||||||
get_points_from_csv(content, self.request.user.customuser)
|
result = get_points_from_csv(content, self.request.user.customuser)
|
||||||
|
|
||||||
|
# Обработка нового формата результата
|
||||||
|
success_msg = f"Данные успешно загружены! Создано источников: {result['new_sources']}, добавлено точек: {result['added']}"
|
||||||
|
if result['skipped'] > 0:
|
||||||
|
success_msg += f", пропущено дубликатов: {result['skipped']}"
|
||||||
|
messages.success(self.request, success_msg)
|
||||||
|
|
||||||
|
if result['errors']:
|
||||||
|
messages.warning(
|
||||||
|
self.request,
|
||||||
|
f"Обнаружено ошибок: {len(result['errors'])}. Первые ошибки: " + "; ".join(result['errors'][:5])
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
|
||||||
return redirect("mainapp:load_csv_data")
|
return redirect("mainapp:load_csv_data")
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build:
|
# build:
|
||||||
context: ./dbapp
|
# context: ./dbapp
|
||||||
dockerfile: Dockerfile
|
# dockerfile: Dockerfile
|
||||||
|
image: https://registry.geraltserv.ru/geolocation:latest
|
||||||
env_file:
|
env_file:
|
||||||
- .env.prod
|
- .env.prod
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -14,9 +15,10 @@ services:
|
|||||||
- 8000
|
- 8000
|
||||||
|
|
||||||
worker:
|
worker:
|
||||||
build:
|
# build:
|
||||||
context: ./dbapp
|
# context: ./dbapp
|
||||||
dockerfile: Dockerfile
|
# dockerfile: Dockerfile
|
||||||
|
image: https://registry.geraltserv.ru/geolocation:latest
|
||||||
env_file:
|
env_file:
|
||||||
- .env.prod
|
- .env.prod
|
||||||
#entrypoint: []
|
#entrypoint: []
|
||||||
|
|||||||
Reference in New Issue
Block a user