Виджет с усреднёнными точками на карте

This commit is contained in:
2025-11-14 16:58:13 +03:00
parent d61236dee2
commit bc226bfc1a
16 changed files with 2268 additions and 14 deletions

View File

@@ -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