Добавил разделение по исчтоника и поправил функцию импорта из Excel csv

This commit is contained in:
2025-11-12 23:49:58 +03:00
parent a7e8f81ef3
commit 50498166e5
6 changed files with 1395 additions and 211 deletions

View File

@@ -104,15 +104,6 @@ class ActionsPageView(View):
return render(request, "mainapp/login_required.html")
class HomePageView(View):
def get(self, request):
if request.user.is_authenticated:
# Redirect to objitem list if authenticated
return redirect("mainapp:objitem_list")
else:
return render(request, "mainapp/login_required.html")
class LoadExcelDataView(LoginRequiredMixin, FormMessageMixin, FormView):
template_name = "mainapp/add_data_from_excel.html"
form_class = LoadExcelData
@@ -558,6 +549,275 @@ class SigmaParameterDataAPIView(LoginRequiredMixin, View):
return JsonResponse({'error': str(e)}, status=500)
class SourceObjItemsAPIView(LoginRequiredMixin, View):
"""API для получения списка ObjItem, связанных с источником"""
def get(self, request, source_id):
from .models import Source
try:
# Загружаем Source с prefetch_related для ObjItem
source = Source.objects.prefetch_related(
'source_objitems',
'source_objitems__parameter_obj',
'source_objitems__parameter_obj__id_satellite',
'source_objitems__parameter_obj__polarization',
'source_objitems__parameter_obj__modulation',
'source_objitems__geo_obj'
).get(id=source_id)
# Получаем все связанные ObjItem, отсортированные по created_at
objitems = source.source_objitems.all().order_by('created_at')
objitems_data = []
for objitem in objitems:
# Получаем данные параметра
param = getattr(objitem, 'parameter_obj', None)
satellite_name = '-'
frequency = '-'
freq_range = '-'
polarization = '-'
bod_velocity = '-'
modulation = '-'
snr = '-'
if param:
if hasattr(param, 'id_satellite') and param.id_satellite:
satellite_name = param.id_satellite.name
frequency = f"{param.frequency:.3f}" if param.frequency is not None else '-'
freq_range = f"{param.freq_range:.3f}" if param.freq_range is not None else '-'
if hasattr(param, 'polarization') and param.polarization:
polarization = param.polarization.name
bod_velocity = f"{param.bod_velocity:.0f}" if param.bod_velocity is not None else '-'
if hasattr(param, 'modulation') and param.modulation:
modulation = param.modulation.name
snr = f"{param.snr:.0f}" if param.snr is not None else '-'
# Получаем геоданные
geo_timestamp = '-'
geo_location = '-'
geo_coords = '-'
if hasattr(objitem, 'geo_obj') and objitem.geo_obj:
if objitem.geo_obj.timestamp:
local_time = timezone.localtime(objitem.geo_obj.timestamp)
geo_timestamp = local_time.strftime("%d.%m.%Y %H:%M")
geo_location = objitem.geo_obj.location or '-'
if objitem.geo_obj.coords:
longitude = objitem.geo_obj.coords.coords[0]
latitude = objitem.geo_obj.coords.coords[1]
lon = f"{longitude}E" if longitude > 0 else f"{abs(longitude)}W"
lat = f"{latitude}N" if latitude > 0 else f"{abs(latitude)}S"
geo_coords = f"{lat} {lon}"
objitems_data.append({
'id': objitem.id,
'name': objitem.name or '-',
'satellite_name': satellite_name,
'frequency': frequency,
'freq_range': freq_range,
'polarization': polarization,
'bod_velocity': bod_velocity,
'modulation': modulation,
'snr': snr,
'geo_timestamp': geo_timestamp,
'geo_location': geo_location,
'geo_coords': geo_coords
})
return JsonResponse({
'source_id': source_id,
'objitems': objitems_data
})
except Source.DoesNotExist:
return JsonResponse({'error': 'Источник не найден'}, status=404)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
class SourceListView(LoginRequiredMixin, View):
"""
Представление для отображения списка источников (Source).
"""
def get(self, request):
from .models import Source
from django.db.models import Count
from datetime import datetime
# Получаем параметры пагинации
page_number, items_per_page = parse_pagination_params(request)
# Получаем параметры сортировки
sort_param = request.GET.get("sort", "-created_at")
# Получаем параметры фильтров
search_query = request.GET.get("search", "").strip()
has_coords_average = request.GET.get("has_coords_average")
has_coords_kupsat = request.GET.get("has_coords_kupsat")
has_coords_valid = request.GET.get("has_coords_valid")
has_coords_reference = request.GET.get("has_coords_reference")
objitem_count_min = request.GET.get("objitem_count_min", "").strip()
objitem_count_max = request.GET.get("objitem_count_max", "").strip()
date_from = request.GET.get("date_from", "").strip()
date_to = request.GET.get("date_to", "").strip()
# Получаем все Source объекты с оптимизацией запросов
sources = Source.objects.select_related(
'created_by__user',
'updated_by__user'
).prefetch_related(
'source_objitems',
'source_objitems__parameter_obj',
'source_objitems__geo_obj'
).annotate(
objitem_count=Count('source_objitems')
)
# Применяем фильтры
# Фильтр по наличию coords_average
if has_coords_average == "1":
sources = sources.filter(coords_average__isnull=False)
elif has_coords_average == "0":
sources = sources.filter(coords_average__isnull=True)
# Фильтр по наличию coords_kupsat
if has_coords_kupsat == "1":
sources = sources.filter(coords_kupsat__isnull=False)
elif has_coords_kupsat == "0":
sources = sources.filter(coords_kupsat__isnull=True)
# Фильтр по наличию coords_valid
if has_coords_valid == "1":
sources = sources.filter(coords_valid__isnull=False)
elif has_coords_valid == "0":
sources = sources.filter(coords_valid__isnull=True)
# Фильтр по наличию coords_reference
if has_coords_reference == "1":
sources = sources.filter(coords_reference__isnull=False)
elif has_coords_reference == "0":
sources = sources.filter(coords_reference__isnull=True)
# Фильтр по количеству ObjItem
if objitem_count_min:
try:
min_count = int(objitem_count_min)
sources = sources.filter(objitem_count__gte=min_count)
except ValueError:
pass
if objitem_count_max:
try:
max_count = int(objitem_count_max)
sources = sources.filter(objitem_count__lte=max_count)
except ValueError:
pass
# Фильтр по диапазону дат создания
if date_from:
try:
date_from_obj = datetime.strptime(date_from, "%Y-%m-%d")
sources = sources.filter(created_at__gte=date_from_obj)
except (ValueError, TypeError):
pass
if date_to:
try:
from datetime import timedelta
date_to_obj = datetime.strptime(date_to, "%Y-%m-%d")
# Добавляем один день чтобы включить весь конечный день
date_to_obj = date_to_obj + timedelta(days=1)
sources = sources.filter(created_at__lt=date_to_obj)
except (ValueError, TypeError):
pass
# Поиск по ID
if search_query:
try:
search_id = int(search_query)
sources = sources.filter(id=search_id)
except ValueError:
# Если не число, игнорируем
pass
# Применяем сортировку
valid_sort_fields = {
"id": "id",
"-id": "-id",
"created_at": "created_at",
"-created_at": "-created_at",
"updated_at": "updated_at",
"-updated_at": "-updated_at",
"objitem_count": "objitem_count",
"-objitem_count": "-objitem_count",
}
if sort_param in valid_sort_fields:
sources = sources.order_by(valid_sort_fields[sort_param])
# Создаем пагинатор
paginator = Paginator(sources, items_per_page)
page_obj = paginator.get_page(page_number)
# Подготавливаем данные для отображения
processed_sources = []
for source in page_obj:
# Форматируем координаты
def format_coords(point):
if point:
longitude = point.coords[0]
latitude = point.coords[1]
lon = f"{longitude}E" if longitude > 0 else f"{abs(longitude)}W"
lat = f"{latitude}N" if latitude > 0 else f"{abs(latitude)}S"
return f"{lat} {lon}"
return "-"
coords_average_str = format_coords(source.coords_average)
coords_kupsat_str = format_coords(source.coords_kupsat)
coords_valid_str = format_coords(source.coords_valid)
coords_reference_str = format_coords(source.coords_reference)
# Получаем количество связанных ObjItem
objitem_count = source.objitem_count
processed_sources.append({
'id': source.id,
'coords_average': coords_average_str,
'coords_kupsat': coords_kupsat_str,
'coords_valid': coords_valid_str,
'coords_reference': coords_reference_str,
'objitem_count': objitem_count,
'created_at': source.created_at,
'updated_at': source.updated_at,
'created_by': source.created_by,
'updated_by': source.updated_by,
})
# Подготавливаем контекст для шаблона
context = {
'page_obj': page_obj,
'processed_sources': processed_sources,
'items_per_page': items_per_page,
'available_items_per_page': [50, 100, 500, 1000],
'sort': sort_param,
'search_query': search_query,
'has_coords_average': has_coords_average,
'has_coords_kupsat': has_coords_kupsat,
'has_coords_valid': has_coords_valid,
'has_coords_reference': has_coords_reference,
'objitem_count_min': objitem_count_min,
'objitem_count_max': objitem_count_max,
'date_from': date_from,
'date_to': date_to,
'full_width_page': True,
}
return render(request, "mainapp/source_list.html", context)
class ProcessKubsatView(LoginRequiredMixin, FormMessageMixin, FormView):
template_name = "mainapp/process_kubsat.html"
form_class = NewEventForm