from django.contrib.auth.mixins import LoginRequiredMixin from django.core.paginator import Paginator from django.db.models import Q from django.views.generic import ListView from .models import LyngSat from mainapp.models import Satellite, Polarization, Modulation, Standard from mainapp.utils import parse_pagination_params class LyngSatListView(LoginRequiredMixin, ListView): """ Представление для отображения списка источников LyngSat с фильтрацией и пагинацией. """ model = LyngSat template_name = 'lyngsatapp/lyngsat_list.html' context_object_name = 'lyngsat_items' paginate_by = 50 def get_queryset(self): """ Возвращает отфильтрованный и отсортированный queryset. """ queryset = LyngSat.objects.select_related( 'id_satellite', 'polarization', 'modulation', 'standard' ).all() # Поиск по ID search_query = self.request.GET.get('search', '').strip() if search_query: try: search_id = int(search_query) queryset = queryset.filter(id=search_id) except ValueError: queryset = queryset.none() # Фильтр по спутнику satellite_ids = self.request.GET.getlist('satellite_id') if satellite_ids: queryset = queryset.filter(id_satellite_id__in=satellite_ids) # Фильтр по поляризации polarization_ids = self.request.GET.getlist('polarization_id') if polarization_ids: queryset = queryset.filter(polarization_id__in=polarization_ids) # Фильтр по модуляции modulation_ids = self.request.GET.getlist('modulation_id') if modulation_ids: queryset = queryset.filter(modulation_id__in=modulation_ids) # Фильтр по стандарту standard_ids = self.request.GET.getlist('standard_id') if standard_ids: queryset = queryset.filter(standard_id__in=standard_ids) # Фильтр по частоте freq_min = self.request.GET.get('freq_min', '').strip() freq_max = self.request.GET.get('freq_max', '').strip() if freq_min: try: queryset = queryset.filter(frequency__gte=float(freq_min)) except ValueError: pass if freq_max: try: queryset = queryset.filter(frequency__lte=float(freq_max)) except ValueError: pass # Фильтр по символьной скорости sym_min = self.request.GET.get('sym_min', '').strip() sym_max = self.request.GET.get('sym_max', '').strip() if sym_min: try: queryset = queryset.filter(sym_velocity__gte=float(sym_min)) except ValueError: pass if sym_max: try: queryset = queryset.filter(sym_velocity__lte=float(sym_max)) except ValueError: pass # Фильтр по дате обновления date_from = self.request.GET.get('date_from', '').strip() date_to = self.request.GET.get('date_to', '').strip() if date_from: queryset = queryset.filter(last_update__gte=date_from) if date_to: queryset = queryset.filter(last_update__lte=date_to) # Сортировка sort = self.request.GET.get('sort', '-id') valid_sort_fields = ['id', '-id', 'frequency', '-frequency', 'sym_velocity', '-sym_velocity', 'last_update', '-last_update'] if sort in valid_sort_fields: queryset = queryset.order_by(sort) else: queryset = queryset.order_by('-id') return queryset def get_context_data(self, **kwargs): """ Добавляет дополнительный контекст для шаблона. """ context = super().get_context_data(**kwargs) # Параметры пагинации page_number, items_per_page = parse_pagination_params(self.request, default_per_page=50) context['items_per_page'] = items_per_page context['available_items_per_page'] = [25, 50, 100, 200, 500] # Пагинация paginator = Paginator(self.get_queryset(), items_per_page) page_obj = paginator.get_page(page_number) context['page_obj'] = page_obj context['lyngsat_items'] = page_obj.object_list # Параметры поиска и фильтрации context['search_query'] = self.request.GET.get('search', '') context['sort'] = self.request.GET.get('sort', '-id') # Данные для фильтров - только спутники с существующими записями LyngSat context['satellites'] = Satellite.objects.filter( lyngsat__isnull=False ).distinct().order_by('name') context['polarizations'] = Polarization.objects.all().order_by('name') context['modulations'] = Modulation.objects.all().order_by('name') context['standards'] = Standard.objects.all().order_by('name') # Выбранные фильтры context['selected_satellites'] = [int(x) for x in self.request.GET.getlist('satellite_id') if x.isdigit()] context['selected_polarizations'] = [int(x) for x in self.request.GET.getlist('polarization_id') if x.isdigit()] context['selected_modulations'] = [int(x) for x in self.request.GET.getlist('modulation_id') if x.isdigit()] context['selected_standards'] = [int(x) for x in self.request.GET.getlist('standard_id') if x.isdigit()] # Параметры фильтров context['freq_min'] = self.request.GET.get('freq_min', '') context['freq_max'] = self.request.GET.get('freq_max', '') context['sym_min'] = self.request.GET.get('sym_min', '') context['sym_max'] = self.request.GET.get('sym_max', '') context['date_from'] = self.request.GET.get('date_from', '') context['date_to'] = self.request.GET.get('date_to', '') return context