diff --git a/dbapp/mainapp/forms.py b/dbapp/mainapp/forms.py index a2ccd03..ebdc32a 100644 --- a/dbapp/mainapp/forms.py +++ b/dbapp/mainapp/forms.py @@ -14,6 +14,9 @@ from .models import ( ) from .widgets import CheckboxSelectMultipleWidget +# Import from mapsapp to avoid circular import issues +from mapsapp.models import Transponders + class UploadFileForm(forms.Form): file = forms.FileField( @@ -530,3 +533,111 @@ class SourceForm(forms.ModelForm): instance.save() return instance + + + +class TransponderForm(forms.ModelForm): + """ + Форма для создания и редактирования транспондеров. + + При редактировании только name, zone_name и snr доступны для изменения. + Остальные поля только для чтения. + """ + + class Meta: + model = Transponders + fields = [ + 'name', + 'sat_id', + 'downlink', + 'uplink', + 'frequency_range', + 'zone_name', + 'polarization', + 'snr', + ] + widgets = { + 'name': forms.TextInput(attrs={ + 'class': 'form-control', + 'placeholder': 'Введите название транспондера' + }), + 'sat_id': forms.Select(attrs={'class': 'form-select'}), + 'downlink': forms.NumberInput(attrs={ + 'class': 'form-control', + 'step': '0.001', + 'placeholder': 'Введите частоту downlink в МГц' + }), + 'uplink': forms.NumberInput(attrs={ + 'class': 'form-control', + 'step': '0.001', + 'placeholder': 'Введите частоту uplink в МГц' + }), + 'frequency_range': forms.NumberInput(attrs={ + 'class': 'form-control', + 'step': '0.001', + 'placeholder': 'Введите полосу частот в МГц' + }), + 'zone_name': forms.TextInput(attrs={ + 'class': 'form-control', + 'placeholder': 'Введите название зоны покрытия' + }), + 'polarization': forms.Select(attrs={'class': 'form-select'}), + 'snr': forms.NumberInput(attrs={ + 'class': 'form-control', + 'step': '0.1', + 'placeholder': 'Введите ОСШ в дБ' + }), + } + labels = { + 'name': 'Название транспондера', + 'sat_id': 'Спутник', + 'downlink': 'Downlink (МГц)', + 'uplink': 'Uplink (МГц)', + 'frequency_range': 'Полоса частот (МГц)', + 'zone_name': 'Название зоны покрытия', + 'polarization': 'Поляризация', + 'snr': 'ОСШ (дБ)', + } + help_texts = { + 'downlink': 'Частота downlink в МГц', + 'uplink': 'Частота uplink в МГц', + 'frequency_range': 'Полоса частот в МГц', + 'snr': 'Отношение сигнал/шум в децибелах', + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Загружаем choices для select полей + self.fields['sat_id'].queryset = Satellite.objects.all().order_by('name') + self.fields['polarization'].queryset = Polarization.objects.all().order_by('name') + + # Если это форма редактирования (instance существует), делаем поля readonly + if self.instance and self.instance.pk: + # Поля только для чтения при редактировании + readonly_fields = ['sat_id', 'downlink', 'uplink', 'frequency_range', 'polarization'] + for field_name in readonly_fields: + self.fields[field_name].widget.attrs['readonly'] = True + self.fields[field_name].widget.attrs['disabled'] = True + self.fields[field_name].required = False + else: + # При создании все поля обязательны кроме name, zone_name и snr + self.fields['sat_id'].required = True + self.fields['downlink'].required = True + self.fields['name'].required = False + self.fields['zone_name'].required = False + self.fields['snr'].required = False + + def clean(self): + """Дополнительная валидация формы.""" + cleaned_data = super().clean() + + # При редактировании восстанавливаем значения readonly полей из instance + if self.instance and self.instance.pk: + cleaned_data['sat_id'] = self.instance.sat_id + cleaned_data['downlink'] = self.instance.downlink + cleaned_data['uplink'] = self.instance.uplink + cleaned_data['frequency_range'] = self.instance.frequency_range + cleaned_data['polarization'] = self.instance.polarization + + return cleaned_data diff --git a/dbapp/mainapp/templates/mainapp/components/_navbar.html b/dbapp/mainapp/templates/mainapp/components/_navbar.html index 6d3d49d..89627f5 100644 --- a/dbapp/mainapp/templates/mainapp/components/_navbar.html +++ b/dbapp/mainapp/templates/mainapp/components/_navbar.html @@ -16,6 +16,9 @@
+ Вы собираетесь удалить {{ total_sources }} источник(ов). + Это действие также удалит {{ total_objitems }} связанных точек. +
++ Это действие необратимо! Все данные будут безвозвратно удалены. +
+| ID источника | +Кол-во точек | +Спутники | +
|---|---|---|
| {{ source.id }} | ++ {{ source.objitem_count }} + | +{{ source.satellites }} | +