From d9cb2433885c585b3159a3b980b380000aad62f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=88=D0=BA=D0=B8=D0=BD=20=D0=A1=D0=B5=D1=80?= =?UTF-8?q?=D0=B3=D0=B5=D0=B9?= Date: Sun, 16 Nov 2025 00:16:50 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dbapp/dbapp/urls.py | 1 + .../templates/lyngsatapp/lyngsat_list.html | 428 ++++++++++++++++++ dbapp/lyngsatapp/urls.py | 8 + dbapp/lyngsatapp/views.py | 148 +++++- dbapp/mainapp/templates/mainapp/actions.html | 22 + .../templates/mainapp/components/_navbar.html | 6 + .../templates/mainapp/source_list.html | 383 ++++++++++++++-- .../mainapp/unlink_lyngsat_confirm.html | 79 ++++ dbapp/mainapp/urls.py | 2 + dbapp/mainapp/views/__init__.py | 2 + dbapp/mainapp/views/api.py | 81 +++- dbapp/mainapp/views/lyngsat.py | 60 ++- dbapp/mainapp/views/source.py | 26 +- 13 files changed, 1198 insertions(+), 48 deletions(-) create mode 100644 dbapp/lyngsatapp/templates/lyngsatapp/lyngsat_list.html create mode 100644 dbapp/lyngsatapp/urls.py create mode 100644 dbapp/mainapp/templates/mainapp/unlink_lyngsat_confirm.html diff --git a/dbapp/dbapp/urls.py b/dbapp/dbapp/urls.py index 6a9a9d7..480e0db 100644 --- a/dbapp/dbapp/urls.py +++ b/dbapp/dbapp/urls.py @@ -24,6 +24,7 @@ urlpatterns = [ path('admin/', admin.site.urls, name='admin'), path('', include('mainapp.urls', namespace='mainapp')), path('', include('mapsapp.urls', namespace='mapsapp')), + path('lyngsat/', include('lyngsatapp.urls', namespace='lyngsatapp')), # Authentication URLs path('login/', auth_views.LoginView.as_view(), name='login'), path('logout/', custom_logout, name='logout'), diff --git a/dbapp/lyngsatapp/templates/lyngsatapp/lyngsat_list.html b/dbapp/lyngsatapp/templates/lyngsatapp/lyngsat_list.html new file mode 100644 index 0000000..df54ca6 --- /dev/null +++ b/dbapp/lyngsatapp/templates/lyngsatapp/lyngsat_list.html @@ -0,0 +1,428 @@ +{% extends 'mainapp/base.html' %} + +{% block title %}Источники LyngSat{% endblock %} + +{% block extra_css %} + +{% endblock %} + +{% block content %} +
+
+
+

Источники LyngSat

+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+ + +
+ + +
+ + +
+ +
+ + +
+ {% include 'mainapp/components/_pagination.html' with page_obj=page_obj show_info=True %} +
+
+
+
+
+
+ + +
+
+
Фильтры
+ +
+
+
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + +
+ + Сбросить +
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + {% for item in lyngsat_items %} + + + + + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
+ + ID + {% if sort == 'id' %} + + {% elif sort == '-id' %} + + {% endif %} + + Спутник + + Частота, МГц + {% if sort == 'frequency' %} + + {% elif sort == '-frequency' %} + + {% endif %} + + Поляризация + + Сим. скорость, БОД + {% if sort == 'sym_velocity' %} + + {% elif sort == '-sym_velocity' %} + + {% endif %} + + МодуляцияСтандартFECОписание + + Обновлено + {% if sort == 'last_update' %} + + {% elif sort == '-last_update' %} + + {% endif %} + + Ссылка
{{ item.id }}{{ item.id_satellite.name|default:"-" }}{{ item.frequency|floatformat:3|default:"-" }}{{ item.polarization.name|default:"-" }}{{ item.sym_velocity|floatformat:3|default:"-" }}{{ item.modulation.name|default:"-" }}{{ item.standard.name|default:"-" }}{{ item.fec|default:"-" }}{{ item.channel_info|default:"-" }}{{ item.last_update|date:"d.m.Y"|default:"-" }} + {% if item.url %} + + + + {% else %} + - + {% endif %} +
Нет данных для отображения
+
+
+
+
+
+
+ +{% endblock %} + +{% block extra_js %} + +{% endblock %} diff --git a/dbapp/lyngsatapp/urls.py b/dbapp/lyngsatapp/urls.py new file mode 100644 index 0000000..555b2b5 --- /dev/null +++ b/dbapp/lyngsatapp/urls.py @@ -0,0 +1,8 @@ +from django.urls import path +from . import views + +app_name = 'lyngsatapp' + +urlpatterns = [ + path('', views.LyngSatListView.as_view(), name='lyngsat_list'), +] diff --git a/dbapp/lyngsatapp/views.py b/dbapp/lyngsatapp/views.py index c60c790..d84885d 100644 --- a/dbapp/lyngsatapp/views.py +++ b/dbapp/lyngsatapp/views.py @@ -1,3 +1,147 @@ -from django.shortcuts import render +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 -# Create your views here. +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') + + # Данные для фильтров + context['satellites'] = Satellite.objects.all().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 diff --git a/dbapp/mainapp/templates/mainapp/actions.html b/dbapp/mainapp/templates/mainapp/actions.html index a0fd494..5dd08b2 100644 --- a/dbapp/mainapp/templates/mainapp/actions.html +++ b/dbapp/mainapp/templates/mainapp/actions.html @@ -205,6 +205,28 @@ + + +
+
+
+
+
+ + + + + +
+

Отвязка всех источников LyngSat

+
+

Отвязать все источники LyngSat от объектов. Все объекты перестанут отображаться как "ТВ" источники. Операция обратима через повторную привязку.

+ + Отвязать все источники + +
+
+
{% endblock %} \ No newline at end of file diff --git a/dbapp/mainapp/templates/mainapp/components/_navbar.html b/dbapp/mainapp/templates/mainapp/components/_navbar.html index 89627f5..7c19f8c 100644 --- a/dbapp/mainapp/templates/mainapp/components/_navbar.html +++ b/dbapp/mainapp/templates/mainapp/components/_navbar.html @@ -16,9 +16,15 @@ + + diff --git a/dbapp/mainapp/templates/mainapp/source_list.html b/dbapp/mainapp/templates/mainapp/source_list.html index 20081f6..2058db8 100644 --- a/dbapp/mainapp/templates/mainapp/source_list.html +++ b/dbapp/mainapp/templates/mainapp/source_list.html @@ -192,6 +192,23 @@ + +
+ +
+
+ + +
+
+ + +
+
+
+
@@ -246,6 +263,9 @@ Координаты Кубсата Координаты оперативников Координаты справочные + {% if has_any_lyngsat %} + Тип источника + {% endif %} Кол-во точек @@ -292,6 +312,18 @@ {{ source.coords_kupsat }} {{ source.coords_valid }} {{ source.coords_reference }} + {% if has_any_lyngsat %} + + {% if source.has_lyngsat %} + + ТВ + + {% else %} + - + {% endif %} + + {% endif %} {{ source.objitem_count }} {{ source.created_at|date:"d.m.Y H:i" }} {{ source.updated_at|date:"d.m.Y H:i" }} @@ -360,7 +392,7 @@