Страница с Кубсатами
This commit is contained in:
@@ -8,7 +8,7 @@ from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||
from django.contrib.gis.geos import Point, Polygon as GEOSPolygon
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Count, Q
|
||||
from django.db.models import Count, Prefetch, Q
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
@@ -234,10 +234,109 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
objitem_filter_q &= Q(source_objitems__geo_obj__coords__within=polygon_geom)
|
||||
has_objitem_filter = True
|
||||
|
||||
# Build filtered objitems queryset for prefetch
|
||||
from ..models import ObjItem
|
||||
filtered_objitems_qs = ObjItem.objects.select_related(
|
||||
'parameter_obj',
|
||||
'parameter_obj__id_satellite',
|
||||
'parameter_obj__polarization',
|
||||
'parameter_obj__modulation',
|
||||
'parameter_obj__standard',
|
||||
'geo_obj',
|
||||
'lyngsat_source',
|
||||
'lyngsat_source__id_satellite',
|
||||
'lyngsat_source__polarization',
|
||||
'lyngsat_source__modulation',
|
||||
'lyngsat_source__standard',
|
||||
'transponder',
|
||||
'created_by',
|
||||
'created_by__user',
|
||||
'updated_by',
|
||||
'updated_by__user',
|
||||
).prefetch_related(
|
||||
'geo_obj__mirrors',
|
||||
)
|
||||
|
||||
# Apply the same filters to prefetch queryset
|
||||
if search_by_name:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(name__icontains=search_query)
|
||||
if geo_date_from:
|
||||
try:
|
||||
geo_date_from_obj = datetime.strptime(geo_date_from, "%Y-%m-%d")
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(geo_obj__timestamp__gte=geo_date_from_obj)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if geo_date_to:
|
||||
try:
|
||||
from datetime import timedelta
|
||||
geo_date_to_obj = datetime.strptime(geo_date_to, "%Y-%m-%d")
|
||||
geo_date_to_obj = geo_date_to_obj + timedelta(days=1)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(geo_obj__timestamp__lt=geo_date_to_obj)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if selected_satellites:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__id_satellite_id__in=selected_satellites)
|
||||
if selected_polarizations:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__polarization_id__in=selected_polarizations)
|
||||
if selected_modulations:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__modulation_id__in=selected_modulations)
|
||||
if freq_min:
|
||||
try:
|
||||
freq_min_val = float(freq_min)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__frequency__gte=freq_min_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_max:
|
||||
try:
|
||||
freq_max_val = float(freq_max)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__frequency__lte=freq_max_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_range_min:
|
||||
try:
|
||||
freq_range_min_val = float(freq_range_min)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__freq_range__gte=freq_range_min_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_range_max:
|
||||
try:
|
||||
freq_range_max_val = float(freq_range_max)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__freq_range__lte=freq_range_max_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if bod_velocity_min:
|
||||
try:
|
||||
bod_velocity_min_val = float(bod_velocity_min)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__bod_velocity__gte=bod_velocity_min_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if bod_velocity_max:
|
||||
try:
|
||||
bod_velocity_max_val = float(bod_velocity_max)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__bod_velocity__lte=bod_velocity_max_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if snr_min:
|
||||
try:
|
||||
snr_min_val = float(snr_min)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__snr__gte=snr_min_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if snr_max:
|
||||
try:
|
||||
snr_max_val = float(snr_max)
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(parameter_obj__snr__lte=snr_max_val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if selected_mirrors:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(geo_obj__mirrors__id__in=selected_mirrors)
|
||||
if polygon_geom:
|
||||
filtered_objitems_qs = filtered_objitems_qs.filter(geo_obj__coords__within=polygon_geom)
|
||||
|
||||
# Get all Source objects with query optimization
|
||||
# Using annotate to count ObjItems efficiently (single query with GROUP BY)
|
||||
# Using select_related for ForeignKey/OneToOne relationships to avoid N+1 queries
|
||||
# Using prefetch_related for reverse ForeignKey and ManyToMany relationships
|
||||
# Using Prefetch with filtered queryset to avoid N+1 queries in display loop
|
||||
sources = Source.objects.select_related(
|
||||
'info', # ForeignKey to ObjectInfo
|
||||
'created_by', # ForeignKey to CustomUser
|
||||
@@ -245,25 +344,8 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
'updated_by', # ForeignKey to CustomUser
|
||||
'updated_by__user', # OneToOne to User
|
||||
).prefetch_related(
|
||||
# Prefetch related objitems with their nested relationships
|
||||
'source_objitems',
|
||||
'source_objitems__parameter_obj',
|
||||
'source_objitems__parameter_obj__id_satellite',
|
||||
'source_objitems__parameter_obj__polarization',
|
||||
'source_objitems__parameter_obj__modulation',
|
||||
'source_objitems__parameter_obj__standard',
|
||||
'source_objitems__geo_obj',
|
||||
'source_objitems__geo_obj__mirrors',
|
||||
'source_objitems__lyngsat_source',
|
||||
'source_objitems__lyngsat_source__id_satellite',
|
||||
'source_objitems__lyngsat_source__polarization',
|
||||
'source_objitems__lyngsat_source__modulation',
|
||||
'source_objitems__lyngsat_source__standard',
|
||||
'source_objitems__transponder',
|
||||
'source_objitems__created_by',
|
||||
'source_objitems__created_by__user',
|
||||
'source_objitems__updated_by',
|
||||
'source_objitems__updated_by__user',
|
||||
# Use Prefetch with filtered queryset
|
||||
Prefetch('source_objitems', queryset=filtered_objitems_qs, to_attr='filtered_objitems'),
|
||||
# Prefetch marks with their relationships
|
||||
'marks',
|
||||
'marks__created_by',
|
||||
@@ -525,76 +607,8 @@ class SourceListView(LoginRequiredMixin, View):
|
||||
coords_valid_str = format_coords_display(source.coords_valid)
|
||||
coords_reference_str = format_coords_display(source.coords_reference)
|
||||
|
||||
# Filter objitems for display (to get satellites and lyngsat info)
|
||||
objitems_to_display = source.source_objitems.all()
|
||||
|
||||
# Apply the same filters as in the count annotation
|
||||
if geo_date_from:
|
||||
try:
|
||||
geo_date_from_obj = datetime.strptime(geo_date_from, "%Y-%m-%d")
|
||||
objitems_to_display = objitems_to_display.filter(geo_obj__timestamp__gte=geo_date_from_obj)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if geo_date_to:
|
||||
try:
|
||||
from datetime import timedelta
|
||||
geo_date_to_obj = datetime.strptime(geo_date_to, "%Y-%m-%d")
|
||||
geo_date_to_obj = geo_date_to_obj + timedelta(days=1)
|
||||
objitems_to_display = objitems_to_display.filter(geo_obj__timestamp__lt=geo_date_to_obj)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if selected_satellites:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__id_satellite_id__in=selected_satellites)
|
||||
if selected_polarizations:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__polarization_id__in=selected_polarizations)
|
||||
if selected_modulations:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__modulation_id__in=selected_modulations)
|
||||
if freq_min:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__frequency__gte=float(freq_min))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_max:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__frequency__lte=float(freq_max))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_range_min:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__freq_range__gte=float(freq_range_min))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if freq_range_max:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__freq_range__lte=float(freq_range_max))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if bod_velocity_min:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__bod_velocity__gte=float(bod_velocity_min))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if bod_velocity_max:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__bod_velocity__lte=float(bod_velocity_max))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if snr_min:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__snr__gte=float(snr_min))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if snr_max:
|
||||
try:
|
||||
objitems_to_display = objitems_to_display.filter(parameter_obj__snr__lte=float(snr_max))
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if selected_mirrors:
|
||||
objitems_to_display = objitems_to_display.filter(geo_obj__mirrors__id__in=selected_mirrors)
|
||||
if search_by_name:
|
||||
objitems_to_display = objitems_to_display.filter(name__icontains=search_query)
|
||||
if polygon_geom:
|
||||
objitems_to_display = objitems_to_display.filter(geo_obj__coords__within=polygon_geom)
|
||||
# Use pre-filtered objitems from Prefetch
|
||||
objitems_to_display = source.filtered_objitems
|
||||
|
||||
# Use annotated count (consistent with filtering)
|
||||
objitem_count = source.objitem_count
|
||||
|
||||
Reference in New Issue
Block a user