Исправил отображения объектов в источниках
This commit is contained in:
@@ -30,6 +30,7 @@ from .lyngsat import (
|
||||
FillLyngsatDataView,
|
||||
LyngsatTaskStatusView,
|
||||
ClearLyngsatCacheView,
|
||||
UnlinkAllLyngsatSourcesView,
|
||||
)
|
||||
from .source import SourceListView, SourceUpdateView, SourceDeleteView, DeleteSelectedSourcesView
|
||||
from .transponder import (
|
||||
@@ -78,6 +79,7 @@ __all__ = [
|
||||
'FillLyngsatDataView',
|
||||
'LyngsatTaskStatusView',
|
||||
'ClearLyngsatCacheView',
|
||||
'UnlinkAllLyngsatSourcesView',
|
||||
# Source
|
||||
'SourceListView',
|
||||
'SourceUpdateView',
|
||||
|
||||
@@ -186,7 +186,13 @@ class SourceObjItemsAPIView(LoginRequiredMixin, View):
|
||||
'source_objitems__parameter_obj__id_satellite',
|
||||
'source_objitems__parameter_obj__polarization',
|
||||
'source_objitems__parameter_obj__modulation',
|
||||
'source_objitems__geo_obj'
|
||||
'source_objitems__parameter_obj__standard',
|
||||
'source_objitems__geo_obj',
|
||||
'source_objitems__geo_obj__mirrors',
|
||||
'source_objitems__lyngsat_source',
|
||||
'source_objitems__transponder',
|
||||
'source_objitems__created_by__user',
|
||||
'source_objitems__updated_by__user'
|
||||
).get(id=source_id)
|
||||
|
||||
# Get all related ObjItems, sorted by created_at
|
||||
@@ -202,9 +208,12 @@ class SourceObjItemsAPIView(LoginRequiredMixin, View):
|
||||
polarization = '-'
|
||||
bod_velocity = '-'
|
||||
modulation = '-'
|
||||
standard = '-'
|
||||
snr = '-'
|
||||
parameter_id = None
|
||||
|
||||
if param:
|
||||
parameter_id = param.id
|
||||
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 '-'
|
||||
@@ -214,6 +223,8 @@ class SourceObjItemsAPIView(LoginRequiredMixin, View):
|
||||
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
|
||||
if hasattr(param, 'standard') and param.standard:
|
||||
standard = param.standard.name
|
||||
snr = f"{param.snr:.0f}" if param.snr is not None else '-'
|
||||
|
||||
# Get geo data
|
||||
@@ -235,6 +246,56 @@ class SourceObjItemsAPIView(LoginRequiredMixin, View):
|
||||
lat = f"{latitude}N" if latitude > 0 else f"{abs(latitude)}S"
|
||||
geo_coords = f"{lat} {lon}"
|
||||
|
||||
# Get created/updated info
|
||||
created_at = '-'
|
||||
if objitem.created_at:
|
||||
local_time = timezone.localtime(objitem.created_at)
|
||||
created_at = local_time.strftime("%d.%m.%Y %H:%M")
|
||||
|
||||
updated_at = '-'
|
||||
if objitem.updated_at:
|
||||
local_time = timezone.localtime(objitem.updated_at)
|
||||
updated_at = local_time.strftime("%d.%m.%Y %H:%M")
|
||||
|
||||
created_by = str(objitem.created_by) if objitem.created_by else '-'
|
||||
updated_by = str(objitem.updated_by) if objitem.updated_by else '-'
|
||||
|
||||
# Check for LyngSat
|
||||
has_lyngsat = hasattr(objitem, 'lyngsat_source') and objitem.lyngsat_source is not None
|
||||
lyngsat_id = objitem.lyngsat_source.id if has_lyngsat else None
|
||||
|
||||
# Check for Transponder
|
||||
has_transponder = hasattr(objitem, 'transponder') and objitem.transponder is not None
|
||||
transponder_id = objitem.transponder.id if has_transponder else None
|
||||
transponder_info = '-'
|
||||
if has_transponder:
|
||||
try:
|
||||
downlink = objitem.transponder.downlink if objitem.transponder.downlink else '-'
|
||||
freq_range_t = objitem.transponder.frequency_range if objitem.transponder.frequency_range else '-'
|
||||
transponder_info = f"{downlink}:{freq_range_t}"
|
||||
except Exception:
|
||||
transponder_info = '-'
|
||||
|
||||
# Check for Sigma
|
||||
has_sigma = False
|
||||
sigma_info = '-'
|
||||
if param and hasattr(param, 'sigma_parameter'):
|
||||
sigma_count = param.sigma_parameter.count()
|
||||
if sigma_count > 0:
|
||||
has_sigma = True
|
||||
sigma_info = f"{sigma_count}"
|
||||
|
||||
# Get comment, is_average, and mirrors from geo_obj
|
||||
comment = '-'
|
||||
is_average = '-'
|
||||
mirrors = '-'
|
||||
if hasattr(objitem, 'geo_obj') and objitem.geo_obj:
|
||||
comment = objitem.geo_obj.comment or '-'
|
||||
is_average = 'Да' if objitem.geo_obj.is_average else 'Нет'
|
||||
# Get mirrors list
|
||||
mirrors_list = list(objitem.geo_obj.mirrors.values_list('name', flat=True))
|
||||
mirrors = ', '.join(mirrors_list) if mirrors_list else '-'
|
||||
|
||||
objitems_data.append({
|
||||
'id': objitem.id,
|
||||
'name': objitem.name or '-',
|
||||
@@ -244,10 +305,26 @@ class SourceObjItemsAPIView(LoginRequiredMixin, View):
|
||||
'polarization': polarization,
|
||||
'bod_velocity': bod_velocity,
|
||||
'modulation': modulation,
|
||||
'standard': standard,
|
||||
'snr': snr,
|
||||
'geo_timestamp': geo_timestamp,
|
||||
'geo_location': geo_location,
|
||||
'geo_coords': geo_coords
|
||||
'geo_coords': geo_coords,
|
||||
'created_at': created_at,
|
||||
'updated_at': updated_at,
|
||||
'created_by': created_by,
|
||||
'updated_by': updated_by,
|
||||
'comment': comment,
|
||||
'is_average': is_average,
|
||||
'has_lyngsat': has_lyngsat,
|
||||
'lyngsat_id': lyngsat_id,
|
||||
'has_transponder': has_transponder,
|
||||
'transponder_id': transponder_id,
|
||||
'transponder_info': transponder_info,
|
||||
'has_sigma': has_sigma,
|
||||
'sigma_info': sigma_info,
|
||||
'parameter_id': parameter_id,
|
||||
'mirrors': mirrors,
|
||||
})
|
||||
|
||||
return JsonResponse({
|
||||
|
||||
@@ -46,22 +46,30 @@ class LinkLyngsatSourcesView(LoginRequiredMixin, FormMessageMixin, FormView):
|
||||
|
||||
param = objitem.parameter_obj
|
||||
|
||||
# Round object frequency
|
||||
# Round object frequency to 1 decimal place
|
||||
if param.frequency:
|
||||
rounded_freq = round(param.frequency, 0) # Round to integer
|
||||
rounded_freq = round(param.frequency, 1) # Round to 1 decimal place
|
||||
|
||||
# Find matching LyngSat source
|
||||
# Compare by rounded frequency and polarization
|
||||
# Compare by rounded frequency (with tolerance) and polarization
|
||||
# LyngSat frequencies are also rounded to 1 decimal place for comparison
|
||||
lyngsat_sources = LyngSat.objects.filter(
|
||||
id_satellite=param.id_satellite,
|
||||
polarization=param.polarization,
|
||||
frequency__gte=rounded_freq - frequency_tolerance,
|
||||
frequency__lte=rounded_freq + frequency_tolerance
|
||||
).order_by('frequency')
|
||||
polarization=param.polarization
|
||||
).select_related('id_satellite', 'polarization')
|
||||
|
||||
if lyngsat_sources.exists():
|
||||
# Take first matching source
|
||||
objitem.lyngsat_source = lyngsat_sources.first()
|
||||
# Filter by rounded frequency with tolerance
|
||||
matching_sources = []
|
||||
for lyngsat in lyngsat_sources:
|
||||
if lyngsat.frequency:
|
||||
rounded_lyngsat_freq = round(lyngsat.frequency, 1)
|
||||
if abs(rounded_lyngsat_freq - rounded_freq) <= frequency_tolerance:
|
||||
matching_sources.append(lyngsat)
|
||||
|
||||
if matching_sources:
|
||||
# Take first matching source (sorted by frequency difference)
|
||||
matching_sources.sort(key=lambda x: abs(round(x.frequency, 1) - rounded_freq))
|
||||
objitem.lyngsat_source = matching_sources[0]
|
||||
objitem.save(update_fields=['lyngsat_source'])
|
||||
linked_count += 1
|
||||
|
||||
@@ -159,3 +167,35 @@ class ClearLyngsatCacheView(LoginRequiredMixin, View):
|
||||
def get(self, request):
|
||||
"""Cache management page."""
|
||||
return render(request, 'mainapp/clear_lyngsat_cache.html')
|
||||
|
||||
|
||||
class UnlinkAllLyngsatSourcesView(LoginRequiredMixin, View):
|
||||
"""View for unlinking all LyngSat sources from ObjItems."""
|
||||
|
||||
def post(self, request):
|
||||
"""Unlink all LyngSat sources."""
|
||||
try:
|
||||
# Count objects with LyngSat sources before unlinking
|
||||
linked_count = ObjItem.objects.filter(lyngsat_source__isnull=False).count()
|
||||
|
||||
# Unlink all LyngSat sources
|
||||
ObjItem.objects.filter(lyngsat_source__isnull=False).update(lyngsat_source=None)
|
||||
|
||||
messages.success(
|
||||
request,
|
||||
f"Успешно отвязано {linked_count} объектов от источников LyngSat"
|
||||
)
|
||||
except Exception as e:
|
||||
messages.error(request, f"Ошибка при отвязке источников: {str(e)}")
|
||||
|
||||
return redirect('mainapp:actions')
|
||||
|
||||
def get(self, request):
|
||||
"""Show confirmation page."""
|
||||
# Count objects with LyngSat sources
|
||||
linked_count = ObjItem.objects.filter(lyngsat_source__isnull=False).count()
|
||||
|
||||
context = {
|
||||
'linked_count': linked_count
|
||||
}
|
||||
return render(request, 'mainapp/unlink_lyngsat_confirm.html', context)
|
||||
|
||||
@@ -35,6 +35,7 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
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")
|
||||
has_lyngsat = request.GET.get("has_lyngsat")
|
||||
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()
|
||||
@@ -86,6 +87,14 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
elif has_coords_reference == "0":
|
||||
sources = sources.filter(coords_reference__isnull=True)
|
||||
|
||||
# Filter by LyngSat presence
|
||||
if has_lyngsat == "1":
|
||||
sources = sources.filter(source_objitems__lyngsat_source__isnull=False).distinct()
|
||||
elif has_lyngsat == "0":
|
||||
sources = sources.filter(
|
||||
~Q(source_objitems__lyngsat_source__isnull=False)
|
||||
).distinct()
|
||||
|
||||
# Filter by ObjItem count
|
||||
if objitem_count_min:
|
||||
try:
|
||||
@@ -155,6 +164,8 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
|
||||
# Prepare data for display
|
||||
processed_sources = []
|
||||
has_any_lyngsat = False # Track if any source has LyngSat data
|
||||
|
||||
for source in page_obj:
|
||||
# Format coordinates
|
||||
def format_coords(point):
|
||||
@@ -174,12 +185,21 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
# Get count of related ObjItems
|
||||
objitem_count = source.objitem_count
|
||||
|
||||
# Get satellites for this source
|
||||
# Get satellites for this source and check for LyngSat
|
||||
satellite_names = set()
|
||||
has_lyngsat = False
|
||||
lyngsat_id = None
|
||||
|
||||
for objitem in source.source_objitems.all():
|
||||
if hasattr(objitem, 'parameter_obj') and objitem.parameter_obj:
|
||||
if hasattr(objitem.parameter_obj, 'id_satellite') and objitem.parameter_obj.id_satellite:
|
||||
satellite_names.add(objitem.parameter_obj.id_satellite.name)
|
||||
|
||||
# Check if any objitem has LyngSat
|
||||
if hasattr(objitem, 'lyngsat_source') and objitem.lyngsat_source:
|
||||
has_lyngsat = True
|
||||
lyngsat_id = objitem.lyngsat_source.id
|
||||
has_any_lyngsat = True
|
||||
|
||||
satellite_str = ", ".join(sorted(satellite_names)) if satellite_names else "-"
|
||||
|
||||
@@ -193,6 +213,8 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
'satellite': satellite_str,
|
||||
'created_at': source.created_at,
|
||||
'updated_at': source.updated_at,
|
||||
'has_lyngsat': has_lyngsat,
|
||||
'lyngsat_id': lyngsat_id,
|
||||
})
|
||||
|
||||
# Prepare context for template
|
||||
@@ -207,6 +229,8 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
'has_coords_kupsat': has_coords_kupsat,
|
||||
'has_coords_valid': has_coords_valid,
|
||||
'has_coords_reference': has_coords_reference,
|
||||
'has_lyngsat': has_lyngsat,
|
||||
'has_any_lyngsat': has_any_lyngsat,
|
||||
'objitem_count_min': objitem_count_min,
|
||||
'objitem_count_max': objitem_count_max,
|
||||
'date_from': date_from,
|
||||
|
||||
Reference in New Issue
Block a user