Files
dbstorage/dbapp/mainapp/models.py

305 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.db import models
from django.contrib.auth.models import User
from django.contrib.gis.db import models as gis
from django.contrib.gis.db.models import functions
from django.db.models import F, ExpressionWrapper
from django.utils import timezone
def get_default_polarization():
obj, created = Polarization.objects.get_or_create(
name="-"
)
return obj.id
def get_default_modulation():
obj, created = Modulation.objects.get_or_create(
name="-"
)
return obj.id
def get_default_standard():
obj, created = Standard.objects.get_or_create(
name="-"
)
return obj.id
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
ROLE_CHOICES = [
('admin', 'Администратор'),
('moderator', 'Модератор'),
('user', 'Пользователь'),
]
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user', verbose_name='Роль пользователя')
def __str__(self):
return f"{self.user.first_name} {self.user.last_name}" if self.user.first_name and self.user.last_name else self.user.username
class Meta:
verbose_name = "Пользователь"
verbose_name_plural = "Пользователи"
class SigmaParMark(models.Model):
mark = models.BooleanField(null=True, blank=True, verbose_name="Наличие сигнала")
timestamp = models.DateTimeField(null=True, blank=True, verbose_name="Время")
def __str__(self):
timestamp = self.timestamp.strftime("%d.%m.%Y %H:%M")
return f'+ {timestamp}' if self.mark else f'- {timestamp}'
class Meta:
verbose_name = "Отметка"
verbose_name_plural = "Отметки"
class Mirror(models.Model):
name = models.CharField(max_length=30, unique=True, verbose_name="Имя зеркала")
def __str__(self):
return self.name
class Meta:
verbose_name = "Зеркало"
verbose_name_plural = "Зеркала"
class Polarization(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name="Поляризация")
def __str__(self):
return self.name
class Meta:
verbose_name = "Поляризация"
verbose_name_plural = "Поляризация"
class Modulation(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name="Модуляция", db_index=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Модуляция"
verbose_name_plural = "Модуляции"
class Standard(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name="Стандарт")
def __str__(self):
return self.name
class Meta:
verbose_name = "Стандарт"
verbose_name_plural = "Стандарты"
class Satellite(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name="Имя спутника", db_index=True)
norad = models.IntegerField(blank=True, null=True, verbose_name="NORAD ID")
def __str__(self):
return self.name
class Meta:
verbose_name = "Спутник"
verbose_name_plural = "Спутники"
class ObjItem(models.Model):
name = models.CharField(null=True, blank=True, max_length=100, verbose_name="Имя объекта", db_index=True)
# id_satellite = models.ForeignKey(Satellite, on_delete=models.PROTECT, related_name="objitems", verbose_name="Спутник")
# id_vch_load = models.ForeignKey(Parameter, on_delete=models.CASCADE, related_name="objitems", verbose_name="ВЧ загрузка")
# id_geo = models.ForeignKey(Geo, on_delete=models.CASCADE, related_name="objitems", verbose_name="Геоданные")
# id_user_add = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, related_name="objitems", verbose_name="Пользователь", null=True, blank=True)
# id_source_type = models.ForeignKey(SourceType, on_delete=models.SET_NULL, related_name="objitems", verbose_name='Тип источника', null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
created_by = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, related_name="objitems_created",
null=True, blank=True, verbose_name="Создан пользователем")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Дата последнего изменения")
updated_by = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, related_name="objitems_updated",
null=True, blank=True, verbose_name="Изменен пользователем")
def __str__(self):
return f"Объект {self.name}"
class Meta:
verbose_name = "Объект"
verbose_name_plural = "Объекты"
# constraints = [
# models.UniqueConstraint(
# fields=['id_vch_load', 'id_geo'],
# name='unique_objitem_combination'
# )
# ]
class SourceType(models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name="Тип источника")
objitem = models.OneToOneField(ObjItem, on_delete=models.SET_NULL, verbose_name="Гео", related_name="source_type_obj", null=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Тип источника"
verbose_name_plural = 'Типы источников'
class Parameter(models.Model):
id_satellite = models.ForeignKey(Satellite, on_delete=models.PROTECT, related_name="parameters", verbose_name="Спутник", null=True)
polarization = models.ForeignKey(
Polarization, default=get_default_polarization, on_delete=models.SET_DEFAULT, related_name="polarizations", null=True, blank=True, verbose_name="Поляризация"
)
frequency = models.FloatField(default=0, null=True, blank=True, verbose_name="Частота, МГц", db_index=True)
freq_range = models.FloatField(default=0, null=True, blank=True, verbose_name="Полоса частот, МГц")
bod_velocity = models.FloatField(default=0, null=True, blank=True, verbose_name="Символьная скорость, БОД")
modulation = models.ForeignKey(
Modulation, default=get_default_modulation, on_delete=models.SET_DEFAULT, related_name="modulations", null=True, blank=True, verbose_name="Модуляция"
)
snr = models.FloatField(default=0, null=True, blank=True, verbose_name="ОСШ")
standard = models.ForeignKey(
Standard, default=get_default_standard, on_delete=models.SET_DEFAULT, related_name="standards", null=True, blank=True, verbose_name="Стандарт"
)
id_user_add = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, related_name="parameter_added", verbose_name="Пользователь", null=True, blank=True)
objitems = models.ManyToManyField(ObjItem, related_name="parameters_obj", verbose_name="Источники", blank=True)
# id_sigma_parameter = models.ManyToManyField(SigmaParameter, on_delete=models.SET_NULL, related_name="sigma_parameter", verbose_name="ВЧ с sigma", null=True, blank=True)
# id_sigma_parameter = models.ManyToManyField(SigmaParameter, verbose_name="ВЧ с sigma", null=True, blank=True)
def __str__(self):
polarization_name = self.polarization.name if self.polarization else "-"
modulation_name = self.modulation.name if self.modulation else "-"
return f"Источник-{self.frequency}:{self.freq_range} МГц:{polarization_name}:{modulation_name}"
class Meta:
verbose_name = "ВЧ загрузка"
verbose_name_plural = "ВЧ загрузки"
indexes = [
models.Index(fields=['id_satellite', 'frequency']),
models.Index(fields=['frequency', 'polarization']),
]
# constraints = [
# models.UniqueConstraint(
# fields=[
# 'polarization', 'frequency', 'freq_range',
# 'bod_velocity', 'modulation', 'snr', 'standard'
# ],
# name='unique_parameter_combination'
# )
# ]
class SigmaParameter(models.Model):
TRANSFERS = [
(-1.0, "-"),
(9750.0, "9750 МГц"),
(10750.0, "10750 МГц")
]
id_satellite = models.ForeignKey(Satellite, on_delete=models.PROTECT, related_name="sigmapar_sat", verbose_name="Спутник")
transfer = models.FloatField(
choices=TRANSFERS,
default=-1.0,
verbose_name="Перенос по частоте"
)
status = models.CharField(max_length=20, blank=True, null=True, verbose_name="Статус")
frequency = models.FloatField(default=0, null=True, blank=True, verbose_name="Частота, МГц", db_index=True)
transfer_frequency = models.GeneratedField(
expression=ExpressionWrapper(
F('frequency') + F('transfer'),
output_field=models.FloatField()
),
output_field=models.FloatField(),
db_persist=True,
null=True, blank=True, verbose_name="Частота в Ku, МГц"
)
freq_range = models.FloatField(default=0, null=True, blank=True, verbose_name="Полоса частот, МГц")
power = models.FloatField(default=0, null=True, blank=True, verbose_name="Мощность, дБм")
bod_velocity = models.FloatField(default=0, null=True, blank=True, verbose_name="Символьная скорость, БОД")
polarization = models.ForeignKey(
Polarization, default=get_default_polarization, on_delete=models.SET_DEFAULT, related_name="polarizations_sigma", null=True, blank=True, verbose_name="Поляризация"
)
modulation = models.ForeignKey(
Modulation, default=get_default_modulation, on_delete=models.SET_DEFAULT, related_name="modulations_sigma", null=True, blank=True, verbose_name="Модуляция"
)
snr = models.FloatField(default=0, null=True, blank=True, verbose_name="ОСШ, Дб")
standard = models.ForeignKey(
Standard, default=get_default_standard, on_delete=models.SET_DEFAULT, related_name="standards_sigma", null=True, blank=True, verbose_name="Стандарт"
)
packets = models.BooleanField(null=True, blank=True, verbose_name="Пакетность")
datetime_begin = models.DateTimeField(null=True, blank=True, verbose_name="Время начала измерения")
datetime_end = models.DateTimeField(null=True, blank=True, verbose_name="Время окончания измерения")
mark = models.ManyToManyField(SigmaParMark, verbose_name="Отметка", blank=True)
parameter = models.ForeignKey(
Parameter,
on_delete=models.SET_NULL,
related_name='sigma_parameter',
verbose_name="ВЧ",
null=True,
blank=True
)
def __str__(self):
modulation_name = self.modulation.name if self.modulation else "-"
return f"Sigma-{self.frequency}:{self.freq_range} МГц:{modulation_name}"
class Meta:
verbose_name = "ВЧ sigma"
verbose_name_plural = "ВЧ sigma"
class Geo(models.Model):
mirrors = models.ManyToManyField(Mirror, related_name="geo_mirrors", verbose_name="Зеркала",)
timestamp = models.DateTimeField(null=True, blank=True, verbose_name="Время", db_index=True)
coords = gis.PointField(srid=4326, null=True, blank=True, verbose_name="Координата геолокации")
location = models.CharField(max_length=255, null=True, blank=True, verbose_name="Метоположение")
comment = models.CharField(max_length=255, blank=True, verbose_name="Комментарий")
coords_kupsat = gis.PointField(srid=4326, null=True, blank=True, verbose_name="Координаты Кубсата")
coords_valid = gis.PointField(srid=4326, null=True, blank=True, verbose_name="Координаты оперативников")
is_average = models.BooleanField(null=True, blank=True, verbose_name="Усреднённое")
id_user_add = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, related_name="geos_added", verbose_name="Пользователь", null=True, blank=True)
distance_coords_kup = models.GeneratedField(
expression=functions.Distance("coords", "coords_kupsat")/1000,
output_field=models.FloatField(),
db_persist=True,
null=True, blank=True, verbose_name="Расстояние между купсатом и гео, км"
)
distance_coords_valid = models.GeneratedField(
expression=functions.Distance("coords", "coords_valid")/1000,
output_field=models.FloatField(),
db_persist=True,
null=True, blank=True, verbose_name="Расстояние между гео и оперативным отделом, км"
)
distance_kup_valid = models.GeneratedField(
expression=functions.Distance("coords_valid", "coords_kupsat")/1000,
output_field=models.FloatField(),
db_persist=True,
null=True, blank=True, verbose_name="Расстояние между купсатом и оперативным отделом, км"
)
objitem = models.OneToOneField(ObjItem, on_delete=models.SET_NULL, verbose_name="Гео", related_name="geo_obj", null=True)
def __str__(self):
longitude = self.coords.coords[0]
latitude = self.coords.coords[1]
lon = f"{longitude}E" if longitude > 0 else f"{abs(longitude)}W"
lat = f"{latitude}N" if latitude > 0 else f"{abs(latitude)}S"
return f"{lat} {lon}, {self.location}"
class Meta:
verbose_name = "Гео"
verbose_name_plural = "Гео"
constraints = [
models.UniqueConstraint(
fields=[
'timestamp', 'coords'
],
name='unique_geo_combination'
)
]