From 1d1c42a8e7e998408506aa6918e7e9c78a9b1ecd 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: Thu, 20 Nov 2025 10:50:27 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=83=20=D1=81=20?= =?UTF-8?q?=D0=9A=D1=83=D0=B1=D1=81=D0=B0=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dbapp/KUBSAT_FEATURE.md | 44 +++--- dbapp/mainapp/forms.py | 24 ++-- .../templates/mainapp/components/_navbar.html | 6 +- dbapp/mainapp/templates/mainapp/kubsat.html | 136 ++++++++---------- dbapp/mainapp/views/kubsat.py | 98 ++++++++----- dbapp/mainapp/views/objitem.py | 2 +- 6 files changed, 171 insertions(+), 139 deletions(-) diff --git a/dbapp/KUBSAT_FEATURE.md b/dbapp/KUBSAT_FEATURE.md index f213d75..6a40c56 100644 --- a/dbapp/KUBSAT_FEATURE.md +++ b/dbapp/KUBSAT_FEATURE.md @@ -54,8 +54,23 @@ - Количество точек автоматически пересчитывается при удалении строк - Таблица имеет фиксированную высоту с прокруткой и sticky заголовок -### Выделение по дате -Строки, у которых дата ГЛ попадает в выбранный диапазон дат, **выделяются зеленым цветом**. При этом все объекты остаются в таблице, независимо от фильтра по дате. +### Двухэтапная фильтрация + +Фильтрация происходит в два этапа: + +**Этап 1: Фильтрация по дате ГЛ** +- Если задан диапазон дат (от/до), отображаются только те точки, у которых дата ГЛ попадает в этот диапазон +- Точки без даты ГЛ исключаются, если фильтр по дате задан +- Если фильтр не задан, показываются все точки + +**Этап 2: Фильтрация по количеству точек** +- Применяется к уже отфильтрованным по дате точкам +- Варианты: + - "Все" - показываются источники с любым количеством точек + - "1" - только источники с ровно 1 точкой (после фильтрации по дате) + - "2 и более" - только источники с 2 и более точками (после фильтрации по дате) + +**Важно**: Фильтр по количеству точек учитывает только те точки, которые прошли фильтрацию по дате! ### Управление данными в таблице @@ -63,10 +78,7 @@ - **Кнопка с иконкой корзины** (для каждой точки) - удаляет конкретную точку (ObjItem) из таблицы - **Кнопка с иконкой заполненной корзины** (для первой точки источника) - удаляет все точки источника (Source) из таблицы -**Кнопка "Оставить только подходящие по дате":** -- Удаляет из таблицы все точки, которые НЕ подходят по заданному диапазону дат -- Оставляет только зеленые (выделенные) строки -- Запрашивает подтверждение перед удалением + **Важно**: Все удаления происходят только из таблицы, **БЕЗ удаления из базы данных**. Это позволяет пользователю исключить ненужные записи перед экспортом. @@ -83,7 +95,7 @@ 8. **Обратный канал, МГц** - частота источника 9. **Перенос** - из объекта Transponder 10. **Получено координат, раз** - количество точек (ObjItem), оставшихся в таблице для данного источника -11. **Дата** - пока заполняется как "-" +11. **Период получения координат** - диапазон дат ГЛ в формате "5.11.2025-15.11.2025" (от самой ранней до самой поздней даты среди точек источника). Если все точки имеют одну дату, показывается только одна дата. 12. **Зеркала** - все имена зеркал через перенос строки (из оставшихся точек) 13. **СКО, км** - не заполняется 14. **Примечание** - не заполняется @@ -123,14 +135,13 @@ queryset = Source.objects.select_related('info').prefetch_related( 1. Откройте страницу "Кубсат" из навигационного меню 2. Выберите нужные фильтры (спутники, поляризация, частота и т.д.) -3. Опционально укажите диапазон дат для выделения подходящих точек -4. Нажмите "Применить фильтры" -5. В таблице отобразятся все точки (ObjItem) сгруппированные по источникам (Source) -6. Точки, подходящие по дате, будут выделены зеленым цветом -7. Опционально нажмите "Оставить только подходящие по дате" для быстрого удаления неподходящих точек -8. При необходимости удалите отдельные точки или целые объекты кнопками в колонке "Действия" -9. Нажмите "Экспорт в Excel" для скачивания файла с оставшимися данными -10. Форма не сбрасывается после экспорта - можно продолжить работу +3. Опционально укажите диапазон дат для фильтрации точек по дате ГЛ (Этап 1) +4. Опционально выберите количество точек (1 или 2+) - применяется к отфильтрованным по дате точкам (Этап 2) +5. Нажмите "Применить фильтры" +6. В таблице отобразятся точки (ObjItem) сгруппированные по источникам (Source) +7. При необходимости удалите отдельные точки или целые объекты кнопками в колонке "Действия" +8. Нажмите "Экспорт в Excel" для скачивания файла с оставшимися данными +9. Форма не сбрасывается после экспорта - можно продолжить работу ## Примечания @@ -138,5 +149,6 @@ queryset = Source.objects.select_related('info').prefetch_related( - Удаление точек/объектов из таблицы не влияет на базу данных - Экспортируются только оставшиеся в таблице точки - Координаты в Excel рассчитываются как инкрементальное среднее из оставшихся точек -- Фильтр по дате не скрывает объекты, а только выделяет их цветом +- Фильтр по дате скрывает неподходящие точки (не показывает их в таблице) - Каждая строка таблицы = одна точка (ObjItem), строки группируются по источникам (Source) +- Количество точек в колонке "Кол-во точек" автоматически пересчитывается при удалении строк diff --git a/dbapp/mainapp/forms.py b/dbapp/mainapp/forms.py index 4bebaaa..de3c51e 100644 --- a/dbapp/mainapp/forms.py +++ b/dbapp/mainapp/forms.py @@ -463,7 +463,7 @@ class SourceForm(forms.ModelForm): class Meta: model = Source - fields = ['info'] # Добавляем поле info + fields = ['info'] widgets = { 'info': forms.Select(attrs={ 'class': 'form-select', @@ -555,18 +555,18 @@ class KubsatFilterForm(forms.Form): widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '5'}) ) - band = forms.ModelChoiceField( + band = forms.ModelMultipleChoiceField( queryset=None, - label='Полоса спутника', + label='Диапазоны работы спутника', required=False, - widget=forms.Select(attrs={'class': 'form-select'}) + widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '4'}) ) polarization = forms.ModelMultipleChoiceField( queryset=Polarization.objects.all().order_by('name'), label='Поляризация', required=False, - widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '3'}) + widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '4'}) ) frequency_min = forms.FloatField( @@ -597,7 +597,7 @@ class KubsatFilterForm(forms.Form): queryset=Modulation.objects.all().order_by('name'), label='Модуляция', required=False, - widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '3'}) + widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '4'}) ) object_type = forms.ModelMultipleChoiceField( @@ -624,22 +624,22 @@ class KubsatFilterForm(forms.Form): # Фиктивные фильтры has_plans = forms.ChoiceField( - choices=[('', 'Все'), ('yes', 'Да'), ('no', 'Нет')], - label='Планы на', + choices=[('', 'Неважно'), ('yes', 'Да'), ('no', 'Нет')], + label='Планы на Кубсат', required=False, widget=forms.RadioSelect() ) success_1 = forms.ChoiceField( - choices=[('', 'Все'), ('yes', 'Да'), ('no', 'Нет')], - label='Успех 1', + choices=[('', 'Неважно'), ('yes', 'Да'), ('no', 'Нет')], + label='ГСО успешно?', required=False, widget=forms.RadioSelect() ) success_2 = forms.ChoiceField( - choices=[('', 'Все'), ('yes', 'Да'), ('no', 'Нет')], - label='Успех 2', + choices=[('', 'Неважно'), ('yes', 'Да'), ('no', 'Нет')], + label='Кубсат успешно?', required=False, widget=forms.RadioSelect() ) diff --git a/dbapp/mainapp/templates/mainapp/components/_navbar.html b/dbapp/mainapp/templates/mainapp/components/_navbar.html index dcc5d6f..7d1675c 100644 --- a/dbapp/mainapp/templates/mainapp/components/_navbar.html +++ b/dbapp/mainapp/templates/mainapp/components/_navbar.html @@ -37,11 +37,11 @@ -