добавил таблицу на отдельную страницу вместе с фильтрами

This commit is contained in:
2025-10-31 16:05:16 +03:00
parent 6df48deb3c
commit 78c46a2751
6 changed files with 1300 additions and 179 deletions

View File

@@ -7,6 +7,7 @@ from django.utils.decorators import method_decorator
from django.views import View
from django.views.generic import TemplateView, FormView
from django.contrib.auth.mixins import UserPassesTestMixin
from django.db import models
import pandas as pd
from .utils import (
fill_data_from_df,
@@ -58,7 +59,7 @@ class AddTranspondersView(FormView):
return super().form_invalid(form)
class HomePageView(TemplateView):
template_name = 'mainapp/home.html'
template_name = 'mainapp/actions.html'
class LoadExcelDataView(FormView):
@@ -89,6 +90,9 @@ class LoadExcelDataView(FormView):
from django.views.generic import View
from django.core.paginator import Paginator
from django.db.models import Prefetch
from .models import Satellite, ObjItem, Parameter, Geo
class GetLocationsView(View):
def get(self, request, sat_id):
@@ -272,4 +276,273 @@ class ProcessKubsatView(FormView):
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
return super().form_invalid(form)
class ObjItemListView(View):
def get(self, request):
# Get satellites that have associated objects, sorted alphabetically
satellites = Satellite.objects.filter(parameters__objitems__isnull=False).distinct().order_by('name')
# Get selected satellite from query parameters
selected_sat_id = request.GET.get('satellite_id')
page_number = request.GET.get('page', 1)
items_per_page = request.GET.get('items_per_page', '25') # Default to 25 items per page
# Get filter parameters
freq_min = request.GET.get('freq_min')
freq_max = request.GET.get('freq_max')
range_min = request.GET.get('range_min')
range_max = request.GET.get('range_max')
snr_min = request.GET.get('snr_min')
snr_max = request.GET.get('snr_max')
bod_min = request.GET.get('bod_min')
bod_max = request.GET.get('bod_max')
search_query = request.GET.get('search')
selected_modulations = request.GET.getlist('modulation')
selected_polarizations = request.GET.getlist('polarization')
selected_satellites = request.GET.getlist('satellite_id')
has_kupsat = request.GET.get('has_kupsat')
has_valid = request.GET.get('has_valid')
try:
items_per_page = int(items_per_page)
except ValueError:
items_per_page = 25
# Only filter objects by selected satellite if provided (no data shown by default)
objects = ObjItem.objects.none() # Initially empty
if selected_satellites or selected_sat_id:
# Handle single satellite from old parameter or multiple from new parameter
if selected_sat_id and not selected_satellites:
# For backward compatibility - if only single satellite parameter is provided
try:
selected_sat_id_single = int(selected_sat_id)
selected_satellites = [selected_sat_id_single]
except ValueError:
selected_satellites = []
# Start with the basic filter if any satellites are selected
if selected_satellites:
# Start with the basic filter
objects = ObjItem.objects.select_related(
'id_user_add__user',
'geo_obj'
).prefetch_related(
'parameters_obj__id_satellite',
'parameters_obj__polarization',
'parameters_obj__modulation',
'parameters_obj__standard'
).filter(parameters_obj__id_satellite_id__in=selected_satellites)
else:
# If no satellites are selected, start with all objects
objects = ObjItem.objects.select_related(
'id_user_add__user',
'geo_obj'
).prefetch_related(
'parameters_obj__id_satellite',
'parameters_obj__polarization',
'parameters_obj__modulation',
'parameters_obj__standard'
)
# Apply additional filters
# Frequency filter
if freq_min is not None and freq_min.strip() != '':
try:
freq_min_val = float(freq_min)
objects = objects.filter(parameters_obj__frequency__gte=freq_min_val)
except ValueError:
pass
if freq_max is not None and freq_max.strip() != '':
try:
freq_max_val = float(freq_max)
objects = objects.filter(parameters_obj__frequency__lte=freq_max_val)
except ValueError:
pass
# Range filter
if range_min is not None and range_min.strip() != '':
try:
range_min_val = float(range_min)
objects = objects.filter(parameters_obj__freq_range__gte=range_min_val)
except ValueError:
pass
if range_max is not None and range_max.strip() != '':
try:
range_max_val = float(range_max)
objects = objects.filter(parameters_obj__freq_range__lte=range_max_val)
except ValueError:
pass
# SNR filter
if snr_min is not None and snr_min.strip() != '':
try:
snr_min_val = float(snr_min)
objects = objects.filter(parameters_obj__snr__gte=snr_min_val)
except ValueError:
pass
if snr_max is not None and snr_max.strip() != '':
try:
snr_max_val = float(snr_max)
objects = objects.filter(parameters_obj__snr__lte=snr_max_val)
except ValueError:
pass
# Symbol rate filter
if bod_min is not None and bod_min.strip() != '':
try:
bod_min_val = float(bod_min)
objects = objects.filter(parameters_obj__bod_velocity__gte=bod_min_val)
except ValueError:
pass
if bod_max is not None and bod_max.strip() != '':
try:
bod_max_val = float(bod_max)
objects = objects.filter(parameters_obj__bod_velocity__lte=bod_max_val)
except ValueError:
pass
# Modulation filter
if selected_modulations:
objects = objects.filter(parameters_obj__modulation__id__in=selected_modulations)
# Polarization filter
if selected_polarizations:
objects = objects.filter(parameters_obj__polarization__id__in=selected_polarizations)
# Kupsat coords filter
if has_kupsat == '1': # has coords
objects = objects.filter(geo_obj__coords_kupsat__isnull=False)
elif has_kupsat == '0': # no coords
objects = objects.filter(geo_obj__coords_kupsat__isnull=True)
# Valid coords filter
if has_valid == '1': # has coords
objects = objects.filter(geo_obj__coords_valid__isnull=False)
elif has_valid == '0': # no coords
objects = objects.filter(geo_obj__coords_valid__isnull=True)
# Add search functionality - search only in name and location fields to avoid spatial lookup errors
if search_query:
search_query = search_query.strip()
if search_query:
# Search in name and location fields to match displayed text
objects = objects.filter(
models.Q(name__icontains=search_query) |
models.Q(geo_obj__location__icontains=search_query)
)
else:
selected_sat_id = None
# Add pagination
paginator = Paginator(objects, items_per_page)
page_obj = paginator.get_page(page_number)
# Prepare the data to include calculated fields for the template
processed_objects = []
for obj in page_obj:
# Get the first parameter
param = obj.parameters_obj.first() if obj.parameters_obj.exists() else None
# Process geo coordinates
geo_coords = "-"
kupsat_coords = "-"
valid_coords = "-"
distance_geo_kup = "-"
distance_geo_valid = "-"
distance_kup_valid = "-"
if obj.geo_obj:
# Format geo coordinates
if obj.geo_obj.coords:
longitude = obj.geo_obj.coords.coords[0]
latitude = obj.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}"
# Format kupsat coordinates
if obj.geo_obj.coords_kupsat:
longitude = obj.geo_obj.coords_kupsat.coords[0]
latitude = obj.geo_obj.coords_kupsat.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"
kupsat_coords = f"{lat} {lon}"
elif obj.geo_obj.coords_kupsat is not None:
kupsat_coords = "-"
# Format valid coordinates
if obj.geo_obj.coords_valid:
longitude = obj.geo_obj.coords_valid.coords[0]
latitude = obj.geo_obj.coords_valid.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"
valid_coords = f"{lat} {lon}"
elif obj.geo_obj.coords_valid is not None:
valid_coords = "-"
# Format distances
if obj.geo_obj.distance_coords_kup is not None:
distance_geo_kup = f"{obj.geo_obj.distance_coords_kup:.3f}"
if obj.geo_obj.distance_coords_valid is not None:
distance_geo_valid = f"{obj.geo_obj.distance_coords_valid:.3f}"
if obj.geo_obj.distance_kup_valid is not None:
distance_kup_valid = f"{obj.geo_obj.distance_kup_valid:.3f}"
processed_objects.append({
'id': obj.id,
'name': obj.name or "-",
'satellite_name': param.id_satellite.name if param and param.id_satellite else "-",
'frequency': f"{param.frequency:.3f}" if param and param.frequency else "-",
'freq_range': f"{param.freq_range:.3f}" if param and param.freq_range else "-",
'polarization': param.polarization.name if param and param.polarization else "-",
'bod_velocity': f"{param.bod_velocity:.3f}" if param and param.bod_velocity else "-",
'modulation': param.modulation.name if param and param.modulation else "-",
'snr': f"{param.snr:.3f}" if param and param.snr else "-",
'geo_coords': geo_coords,
'kupsat_coords': kupsat_coords,
'valid_coords': valid_coords,
'distance_geo_kup': distance_geo_kup,
'distance_geo_valid': distance_geo_valid,
'distance_kup_valid': distance_kup_valid,
'obj': obj
})
# Get all modulations and polarizations for filter dropdowns
from .models import Modulation, Polarization
modulations = Modulation.objects.all()
polarizations = Polarization.objects.all()
context = {
'satellites': satellites,
'selected_satellite_id': selected_sat_id,
'page_obj': page_obj,
'processed_objects': processed_objects,
'items_per_page': items_per_page,
'available_items_per_page': [10, 25, 50, 100],
# Filter values
'freq_min': freq_min,
'freq_max': freq_max,
'range_min': range_min,
'range_max': range_max,
'snr_min': snr_min,
'snr_max': snr_max,
'bod_min': bod_min,
'bod_max': bod_max,
'search_query': search_query,
'selected_modulations': [int(x) for x in selected_modulations if x.isdigit()],
'selected_polarizations': [int(x) for x in selected_polarizations if x.isdigit()],
'selected_satellites': [int(x) for x in selected_satellites if x.isdigit()],
'has_kupsat': has_kupsat,
'has_valid': has_valid,
# For filter dropdowns
'modulations': modulations,
'polarizations': polarizations,
# Enable full width layout
'full_width_page': True,
}
return render(request, 'mainapp/objitem_list.html', context)