@@ -279,7 +279,7 @@ document.addEventListener('DOMContentLoaded', function() {
{column: "frequency", dir: "asc"}
],
columns: [
- {title: "Источник", field: "source_name", minWidth: 180, widthGrow: 2},
+ {title: "Объект", field: "source_name", minWidth: 180, widthGrow: 2},
{title: "Групп", field: "groups_count", minWidth: 70, hozAlign: "center"},
{title: "Точек", field: "total_points", minWidth: 70, hozAlign: "center"},
{title: "Частота", field: "frequency", minWidth: 100, sorter: "number"},
@@ -327,7 +327,7 @@ document.addEventListener('DOMContentLoaded', function() {
// Delete source
function deleteSource(sourceIdx) {
- //if (!confirm('Удалить этот источник со всеми группами?')) return;
+ //if (!confirm('Удалить этот объект со всеми группами?')) return;
allSourcesData.splice(sourceIdx, 1);
updateSourcesTable();
}
@@ -338,7 +338,7 @@ document.addEventListener('DOMContentLoaded', function() {
const source = allSourcesData[sourceIdx];
if (!source) return;
- document.getElementById('sourceDetailsModalLabel').textContent = `Источник: ${source.source_name}`;
+ document.getElementById('sourceDetailsModalLabel').textContent = `Объект: ${source.source_name}`;
renderModalContent();
const modal = new bootstrap.Modal(document.getElementById('sourceDetailsModal'));
@@ -619,7 +619,7 @@ document.addEventListener('DOMContentLoaded', function() {
allSourcesData.forEach(source => {
source.groups.forEach(group => {
summaryData.push({
- 'Источник': source.source_name,
+ 'Объект': source.source_name,
'Частота, МГц': group.frequency,
'Полоса, МГц': group.freq_range,
'Символьная скорость, БОД': group.bod_velocity,
@@ -646,7 +646,7 @@ document.addEventListener('DOMContentLoaded', function() {
source.groups.forEach(group => {
group.points.forEach(point => {
allPointsData.push({
- 'Источник': source.source_name,
+ 'Объект': source.source_name,
'ID точки': point.id,
'Имя точки': point.name,
'Частота, МГц': point.frequency,
diff --git a/dbapp/mainapp/templates/mainapp/source_map.html b/dbapp/mainapp/templates/mainapp/source_map.html
index 8fae63e..c4cb005 100644
--- a/dbapp/mainapp/templates/mainapp/source_map.html
+++ b/dbapp/mainapp/templates/mainapp/source_map.html
@@ -216,7 +216,7 @@
filterPolygon.addTo(map);
// Добавляем popup с информацией
- filterPolygon.bindPopup('Область фильтра
Отображаются только источники с точками в этой области');
+ filterPolygon.bindPopup('Область фильтра
Отображаются только объекты с точками в этой области');
// Если нет других точек, центрируем карту на полигоне
{% if not groups %}
diff --git a/dbapp/mainapp/views/map.py b/dbapp/mainapp/views/map.py
index 059c261..1e5db9e 100644
--- a/dbapp/mainapp/views/map.py
+++ b/dbapp/mainapp/views/map.py
@@ -154,7 +154,7 @@ class ShowSourcesMapView(LoginRequiredMixin, View):
points.append(
{
"point": (coords.x, coords.y), # (lon, lat)
- "source_id": f"Источник #{source.id}",
+ "source_id": f"Объект #{source.id}",
}
)
diff --git a/dbapp/mapsapp/migrations/0003_alter_transponders_sat_id.py b/dbapp/mapsapp/migrations/0003_alter_transponders_sat_id.py
new file mode 100644
index 0000000..5e3d4af
--- /dev/null
+++ b/dbapp/mapsapp/migrations/0003_alter_transponders_sat_id.py
@@ -0,0 +1,20 @@
+# Generated by Django 5.2.7 on 2025-12-03 07:51
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('mainapp', '0017_add_satellite_alternative_name'),
+ ('mapsapp', '0002_alter_transponders_snr'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='transponders',
+ name='sat_id',
+ field=models.ForeignKey(help_text='Спутник, которому принадлежит транспондер', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tran_satellite', to='mainapp.satellite', verbose_name='Спутник'),
+ ),
+ ]
diff --git a/dbapp/mapsapp/models.py b/dbapp/mapsapp/models.py
index 62ac42e..83232f7 100644
--- a/dbapp/mapsapp/models.py
+++ b/dbapp/mapsapp/models.py
@@ -1,149 +1,150 @@
-# Django imports
-from django.core.exceptions import ValidationError
-from django.core.validators import MaxValueValidator, MinValueValidator
-from django.db import models
-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, CustomUser
-
-
-class Transponders(models.Model):
- """
- Модель транспондера спутника.
-
- Хранит информацию о частотах uplink/downlink, зоне покрытия и поляризации.
- """
-
- # Основные поля
- name = models.CharField(
- max_length=30,
- null=True,
- blank=True,
- verbose_name="Название транспондера",
- db_index=True,
- help_text="Название транспондера",
- )
- 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="Название зоны покрытия транспондера",
- )
- snr = models.FloatField(
- blank=True,
- null=True,
- verbose_name="ОСШ, дБ",
- # validators=[MinValueValidator(0), MaxValueValidator(1000)],
- help_text="Отношение сигнал/шум в децибелах",
- )
- created_at = models.DateTimeField(
- auto_now_add=True,
- verbose_name="Дата создания",
- help_text="Дата и время создания записи",
- )
- created_by = models.ForeignKey(
- CustomUser,
- on_delete=models.SET_NULL,
- related_name="transponder_created",
- null=True,
- blank=True,
- verbose_name="Создан пользователем",
- help_text="Пользователь, создавший запись",
- )
- updated_at = models.DateTimeField(
- auto_now=True,
- verbose_name="Дата последнего изменения",
- help_text="Дата и время последнего изменения",
- )
- updated_by = models.ForeignKey(
- CustomUser,
- on_delete=models.SET_NULL,
- related_name="transponder_updated",
- null=True,
- blank=True,
- verbose_name="Изменен пользователем",
- 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="Перенос",
- )
-
- # 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):
- 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"]),
- ]
+# Django imports
+from django.core.exceptions import ValidationError
+from django.core.validators import MaxValueValidator, MinValueValidator
+from django.db import models
+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, CustomUser
+
+
+class Transponders(models.Model):
+ """
+ Модель транспондера спутника.
+
+ Хранит информацию о частотах uplink/downlink, зоне покрытия и поляризации.
+ """
+
+ # Основные поля
+ name = models.CharField(
+ max_length=30,
+ null=True,
+ blank=True,
+ verbose_name="Название транспондера",
+ db_index=True,
+ help_text="Название транспондера",
+ )
+ 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="Название зоны покрытия транспондера",
+ )
+ snr = models.FloatField(
+ blank=True,
+ null=True,
+ verbose_name="ОСШ, дБ",
+ # validators=[MinValueValidator(0), MaxValueValidator(1000)],
+ help_text="Отношение сигнал/шум в децибелах",
+ )
+ created_at = models.DateTimeField(
+ auto_now_add=True,
+ verbose_name="Дата создания",
+ help_text="Дата и время создания записи",
+ )
+ created_by = models.ForeignKey(
+ CustomUser,
+ on_delete=models.SET_NULL,
+ related_name="transponder_created",
+ null=True,
+ blank=True,
+ verbose_name="Создан пользователем",
+ help_text="Пользователь, создавший запись",
+ )
+ updated_at = models.DateTimeField(
+ auto_now=True,
+ verbose_name="Дата последнего изменения",
+ help_text="Дата и время последнего изменения",
+ )
+ updated_by = models.ForeignKey(
+ CustomUser,
+ on_delete=models.SET_NULL,
+ related_name="transponder_updated",
+ null=True,
+ blank=True,
+ verbose_name="Изменен пользователем",
+ 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.SET_NULL,
+ null=True,
+ 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="Перенос",
+ )
+
+ # 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):
+ 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"]),
+ ]
diff --git a/dbapp/test_celery.py b/dbapp/test_celery.py
index fa6dc14..a37480f 100644
--- a/dbapp/test_celery.py
+++ b/dbapp/test_celery.py
@@ -64,5 +64,12 @@ def test_celery_connection():
print("=" * 60)
return True
-if __name__ == "__main__":
- test_celery_connection()
+# if __name__ == "__main__":
+# test_celery_connection()
+import requests
+
+url = f"https://www.lyngsat.com/europe.html"
+payload = {"cmd": "request.get", "url": url, "maxTimeout": 60000}
+response = requests.post("http://localhost:8191/v1", json=payload)
+
+print(response.content)