Рефакторинг и деплоинг

This commit is contained in:
2025-11-09 23:46:08 +03:00
parent 331a9e41cb
commit a0f20f9a60
65 changed files with 5925 additions and 2003 deletions

View File

@@ -1,33 +1,117 @@
# Django imports
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from mainapp.models import Satellite, Polarization, get_default_polarization
from django.db.models import F, ExpressionWrapper
from django.db.models import ExpressionWrapper, F
from django.db.models.functions import Abs
# Local imports
from mainapp.models import Polarization, Satellite, get_default_polarization
class Transponders(models.Model):
name = models.CharField(max_length=30, null=True, blank=True, verbose_name="Название транспондера")
downlink = models.FloatField(blank=True, null=True, verbose_name="Downlink")
frequency_range = models.FloatField(blank=True, null=True, verbose_name="Полоса")
uplink = models.FloatField(blank=True, null=True, verbose_name="Uplink")
zone_name = models.CharField(max_length=255, blank=True, null=True, verbose_name="Название зоны")
polarization = models.ForeignKey(
Polarization, default=get_default_polarization, on_delete=models.SET_DEFAULT, related_name="tran_polarizations", null=True, blank=True, verbose_name="Поляризация"
"""
Модель транспондера спутника.
Хранит информацию о частотах uplink/downlink, зоне покрытия и поляризации.
"""
# Основные поля
name = models.CharField(
max_length=30,
null=True,
blank=True,
verbose_name="Название транспондера",
db_index=True,
help_text="Название транспондера"
)
sat_id = models.ForeignKey(Satellite, on_delete=models.PROTECT, related_name="tran_satellite", verbose_name="Спутник")
transfer =models.GeneratedField(
downlink = models.FloatField(
blank=True,
null=True,
verbose_name="Downlink",
validators=[MinValueValidator(0), MaxValueValidator(50000)],
help_text="Частота downlink в МГц (0-50000)"
)
frequency_range = models.FloatField(
blank=True,
null=True,
verbose_name="Полоса",
validators=[MinValueValidator(0), MaxValueValidator(1000)],
help_text="Полоса частот в МГц (0-1000)"
)
uplink = models.FloatField(
blank=True,
null=True,
verbose_name="Uplink",
validators=[MinValueValidator(0), MaxValueValidator(50000)],
help_text="Частота uplink в МГц (0-50000)"
)
zone_name = models.CharField(
max_length=255,
blank=True,
null=True,
verbose_name="Название зоны",
db_index=True,
help_text="Название зоны покрытия транспондера"
)
# Связи
polarization = models.ForeignKey(
Polarization,
default=get_default_polarization,
on_delete=models.SET_DEFAULT,
related_name="tran_polarizations",
null=True,
blank=True,
verbose_name="Поляризация",
help_text="Поляризация сигнала"
)
sat_id = models.ForeignKey(
Satellite,
on_delete=models.PROTECT,
related_name="tran_satellite",
verbose_name="Спутник",
db_index=True,
help_text="Спутник, которому принадлежит транспондер"
)
# Вычисляемые поля
transfer = models.GeneratedField(
expression=ExpressionWrapper(
Abs(F('downlink') - F('uplink')),
output_field=models.FloatField()
),
output_field=models.FloatField(),
db_persist=True,
null=True, blank=True, verbose_name="Перенос"
null=True,
blank=True,
verbose_name="Перенос"
)
def clean(self):
"""Валидация на уровне модели"""
super().clean()
# Проверка что downlink и uplink заданы
if self.downlink and self.uplink:
# Обычно uplink выше downlink для спутниковой связи
if self.uplink < self.downlink:
raise ValidationError({
'uplink': 'Частота uplink обычно выше частоты downlink'
})
def __str__(self):
return self.name
if self.name:
return self.name
return f"Транспондер {self.sat_id.name if self.sat_id else 'Unknown'}"
class Meta:
verbose_name = "Транспондер"
verbose_name_plural = "Транспондеры"
ordering = ['sat_id', 'downlink']
indexes = [
models.Index(fields=['sat_id', 'downlink']),
models.Index(fields=['sat_id', 'zone_name']),
]