init commit

This commit is contained in:
2025-10-24 13:08:08 +03:00
commit 5e40201460
531 changed files with 919042 additions and 0 deletions

506
dbapp/mainapp/admin.py Normal file
View File

@@ -0,0 +1,506 @@
# admin.py
from django.contrib import admin
from .models import (
Polarization,
Modulation,
Standard,
SigmaParMark,
SigmaParameter,
Parameter,
Satellite,
Mirror,
Geo,
ObjItem,
CustomUser
)
from leaflet.admin import LeafletGeoAdmin
from django import forms
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from django.contrib.gis.db import models as gis
from django.shortcuts import redirect
from django.urls import reverse
from django.utils import timezone
from rangefilter.filters import (
DateRangeFilterBuilder,
DateTimeRangeFilterBuilder,
NumericRangeFilterBuilder,
DateRangeQuickSelectListFilterBuilder,
)
from dynamic_raw_id.admin import DynamicRawIDMixin
from more_admin_filters import MultiSelectDropdownFilter, MultiSelectFilter, MultiSelectRelatedDropdownFilter
from import_export.admin import ImportExportActionModelAdmin
from .filters import GeoKupDistanceFilter, GeoValidDistanceFilter, UniqueToggleFilter, HasSigmaParameterFilter
admin.site.site_title = "Геолокация"
admin.site.site_header = "Geolocation"
admin.site.index_title = "Geo"
admin.site.unregister(User)
admin.site.unregister(Group)
class LocationForm(forms.ModelForm):
latitude_geo = forms.FloatField(required=False, label="Широта")
longitude_geo = forms.FloatField(required=False, label="Долгота")
latitude_kupsat = forms.FloatField(required=False, label="Широта")
longitude_kupsat = forms.FloatField(required=False, label="Долгота")
latitude_valid = forms.FloatField(required=False, label="Широта")
longitude_valid = forms.FloatField(required=False, label="Долгота")
class Meta:
model = Geo
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance and self.instance.coords:
self.fields['latitude_geo'].initial = self.instance.coords[1]
self.fields['longitude_geo'].initial = self.instance.coords[0]
if self.instance and self.instance.coords_kupsat:
self.fields['latitude_kupsat'].initial = self.instance.coords_kupsat[1]
self.fields['longitude_kupsat'].initial = self.instance.coords_kupsat[0]
if self.instance and self.instance.coords_valid:
self.fields['latitude_valid'].initial = self.instance.coords_valid[1]
self.fields['longitude_valid'].initial = self.instance.coords_valid[0]
def save(self, commit=True):
instance = super().save(commit=False)
from django.contrib.gis.geos import Point
lat = self.cleaned_data.get('latitude_geo')
lon = self.cleaned_data.get('longitude_geo')
if lat is not None and lon is not None:
instance.coords = Point(lon, lat, srid=4326)
lat = self.cleaned_data.get('latitude_kupsat')
lon = self.cleaned_data.get('longitude_kupsat')
if lat is not None and lon is not None:
instance.coords_kupsat = Point(lon, lat, srid=4326)
lat = self.cleaned_data.get('latitude_valid')
lon = self.cleaned_data.get('longitude_valid')
if lat is not None and lon is not None:
instance.coords_valid = Point(lon, lat, srid=4326)
if commit:
instance.save()
return instance
class CustomUserInline(admin.StackedInline):
model = CustomUser
can_delete = False
verbose_name_plural = 'Дополнительная информация пользователя'
@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):
list_display = ('user', 'role')
list_filter = ('role',)
class UserAdmin(BaseUserAdmin):
inlines = [CustomUserInline]
admin.site.register(User, UserAdmin)
@admin.register(SigmaParMark)
class SigmaParMarkAdmin(admin.ModelAdmin):
list_display = ("mark", "timestamp")
search_fields = ("mark", )
ordering = ("timestamp",)
@admin.register(Polarization)
class PolarizationAdmin(admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
ordering = ("name",)
@admin.register(Modulation)
class ModulationAdmin(admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
ordering = ("name",)
@admin.register(Standard)
class StandardAdmin(admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
ordering = ("name",)
class SigmaParameterInline(admin.StackedInline):
model = SigmaParameter
extra = 0
autocomplete_fields = ['mark']
readonly_fields = (
"datetime_begin",
"datetime_end",
)
def has_add_permission(self, request, obj=None):
return False
@admin.register(Parameter)
class ParameterAdmin(ImportExportActionModelAdmin, admin.ModelAdmin):
list_display = (
"id_satellite",
"frequency",
"freq_range",
"polarization",
"modulation",
"bod_velocity",
"snr",
"standard",
"sigma_parameter"
)
# fields = ( "id_satellite",
# "frequency",
# "freq_range",
# "polarization",
# "modulation",
# "bod_velocity",
# "snr",
# "standard",
# "id_sigma_parameter")
list_display_links = ("frequency", "id_satellite", )
list_filter = (
HasSigmaParameterFilter,
("id_satellite", MultiSelectRelatedDropdownFilter),
("polarization__name", MultiSelectDropdownFilter),
("modulation", MultiSelectRelatedDropdownFilter),
("standard", MultiSelectRelatedDropdownFilter),
("frequency", NumericRangeFilterBuilder()),
("freq_range", NumericRangeFilterBuilder()),
("snr", NumericRangeFilterBuilder()),
)
search_fields = (
"id_satellite",
"frequency",
"freq_range",
"bod_velocity",
"snr",
"modulation__name",
"polarization__name",
"standard__name",
)
ordering = ("frequency",)
list_select_related = ("polarization", "modulation", "standard", "id_satellite",)
# raw_id_fields = ("id_sigma_parameter", )
inlines = [SigmaParameterInline]
# autocomplete_fields = ("id_sigma_parameter", )
def sigma_parameter(self, obj):
sigma_obj = obj.sigma_parameter.all()
if sigma_obj:
return f"{sigma_obj[0].frequency}: {sigma_obj[0].freq_range}"
return '-'
sigma_parameter.short_description = "ВЧ sigma"
@admin.register(SigmaParameter)
class SigmaParameterAdmin(ImportExportActionModelAdmin, admin.ModelAdmin):
list_display = (
"id_satellite",
"status",
"frequency",
"freq_range",
"power",
"modulation",
"bod_velocity",
"snr",
"standard",
"parameter",
"packets",
"datetime_begin",
"datetime_end",
)
readonly_fields = (
"datetime_begin",
"datetime_end",
)
list_display_links = ("id_satellite",)
list_filter = (
("id_satellite__name", MultiSelectDropdownFilter),
("modulation__name", MultiSelectDropdownFilter),
("standard__name", MultiSelectDropdownFilter),
("frequency", NumericRangeFilterBuilder()),
("freq_range", NumericRangeFilterBuilder()),
("snr", NumericRangeFilterBuilder()),
)
search_fields = (
"id_satellite__name",
"frequency",
"freq_range",
"bod_velocity",
"snr",
"modulation__name",
"standard__name",
)
autocomplete_fields = ('mark',)
ordering = ("frequency",)
list_select_related = ("modulation", "standard", "id_satellite", "parameter")
prefetch_related = ("mark",)
@admin.register(Satellite)
class SatelliteAdmin(admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
ordering = ("name",)
@admin.register(Mirror)
class MirrorAdmin(ImportExportActionModelAdmin, admin.ModelAdmin):
list_display = ("name",)
search_fields = ("name",)
ordering = ("name",)
@admin.register(Geo)
class GeoAdmin(ImportExportActionModelAdmin, LeafletGeoAdmin):
form = LocationForm
readonly_fields = ("distance_coords_kup", "distance_coords_valid", "distance_kup_valid")
fieldsets = (
("Основная информация", {
"fields": ("mirrors", "location", "distance_coords_kup",
"distance_coords_valid", "distance_kup_valid", "timestamp", "comment", "id_user_add")
}),
("Координаты: геолокация", {
"fields": ("longitude_geo", "latitude_geo", "coords"),
}),
("Координаты: Кубсат", {
"fields": ("longitude_kupsat", "latitude_kupsat", "coords_kupsat"),
}),
("Координаты: Оперативный отдел", {
"fields": ("longitude_valid", "latitude_valid", "coords_valid"),
}),
)
list_display = (
"formatted_timestamp",
"location",
"mirrors_names",
"geo_coords",
"kupsat_coords",
"valid_coords",
"is_average",
)
autocomplete_fields = ('mirrors',)
list_display_links = ("formatted_timestamp",)
list_filter = (
("mirrors", MultiSelectRelatedDropdownFilter),
"is_average",
("location", MultiSelectDropdownFilter),
("timestamp", DateRangeQuickSelectListFilterBuilder()),
("id_user_add", MultiSelectRelatedDropdownFilter),
)
search_fields = (
"mirrors__name",
"location",
"coords",
"coords_kupsat",
"coords_valid"
)
list_select_related = ("id_user_add", )
prefetch_related = ("mirrors", )
settings_overrides = {
'DEFAULT_CENTER': (55.7558, 37.6173),
'DEFAULT_ZOOM': 12,
}
def mirrors_names(self, obj):
return ", ".join(m.name for m in obj.mirrors.all())
mirrors_names.short_description = "Зеркала"
def formatted_timestamp(self, obj):
if not obj.timestamp:
return ""
local_time = timezone.localtime(obj.timestamp)
return local_time.strftime("%d.%m.%Y %H:%M:%S")
formatted_timestamp.short_description = "Дата и время"
formatted_timestamp.admin_order_field = "timestamp"
def geo_coords(self, obj):
longitude = obj.coords.coords[0]
latitude = obj.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}"
geo_coords.short_description = "Координаты геолокации"
def kupsat_coords(self, obj):
if obj.coords_kupsat is None:
return "-"
longitude = obj.coords_kupsat.coords[0]
latitude = obj.coords_kupsat.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}"
kupsat_coords.short_description = "Координаты Кубсата"
def valid_coords(self, obj):
if obj.coords_valid is None:
return "-"
longitude = obj.coords_valid.coords[0]
latitude = obj.coords_valid.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}"
valid_coords.short_description = "Координаты оперативного отдела"
def show_on_map(modeladmin, request, queryset):
# Получаем список ID выбранных объектов
selected_ids = queryset.values_list('id', flat=True)
# Формируем строку вида "1,2,3"
ids_str = ','.join(str(pk) for pk in selected_ids)
# Перенаправляем на ваш кастомный view с картой
return redirect(reverse('admin_show_map') + f'?ids={ids_str}')
show_on_map.short_description = "Показать выбранные на карте"
@admin.register(ObjItem)
class ObjectAdmin(admin.ModelAdmin):
list_display = (
"name",
"sat_name",
"freq",
"freq_range",
"pol",
"bod_velocity",
"modulation",
"snr",
"geo_coords",
"kupsat_coords",
"valid_coords",
"distance_geo_kup",
"distance_geo_valid",
"distance_kup_valid",
)
list_display_links = ("name",)
list_filter = (
UniqueToggleFilter,
("id_vch_load__id_satellite", MultiSelectRelatedDropdownFilter),
("id_vch_load__frequency", NumericRangeFilterBuilder()),
("id_vch_load__freq_range", NumericRangeFilterBuilder()),
("id_vch_load__snr", NumericRangeFilterBuilder()),
("id_vch_load__modulation", MultiSelectRelatedDropdownFilter),
("id_vch_load__polarization", MultiSelectRelatedDropdownFilter),
GeoKupDistanceFilter,
GeoValidDistanceFilter
)
search_fields = (
"name",
# "id_geo",
# "id_satellite__name",
# "id_vch_load__frequency",
)
ordering = ("name",)
list_select_related = (
# "id_satellite",
"id_vch_load",
"id_vch_load__polarization",
"id_vch_load__modulation",
"id_vch_load__id_satellite",
"id_geo",
)
autocomplete_fields = ("id_geo",)
raw_id_fields = ("id_vch_load",)
# dynamic_raw_id_fields = ("id_vch_load",)
actions = [show_on_map]
def sat_name(self, obj):
return obj.id_vch_load.id_satellite
sat_name.short_description = "Спутник"
def freq(self, obj):
par = obj.id_vch_load
return par.frequency
freq.short_description = "Частота, МГц"
def distance_geo_kup(self, obj):
par = obj.id_geo.distance_coords_kup
if par is None:
return "-"
return round(par, 3)
distance_geo_kup.short_description = "Гео-куб, км"
def distance_geo_valid(self, obj):
par = obj.id_geo.distance_coords_valid
if par is None:
return "-"
return round(par, 3)
distance_geo_valid.short_description = "Гео-опер, км"
def distance_kup_valid(self, obj):
par = obj.id_geo.distance_kup_valid
if par is None:
return "-"
return round(par, 3)
distance_kup_valid.short_description = "Куб-опер, км"
def pol(self, obj):
par = obj.id_vch_load.polarization
return par.name
pol.short_description = "Поляризация"
def freq_range(self, obj):
par = obj.id_vch_load
return par.freq_range
freq_range.short_description = "Полоса, МГц"
def bod_velocity(self, obj):
par = obj.id_vch_load
return par.bod_velocity
bod_velocity.short_description = "Сим. v, БОД"
def modulation(self, obj):
par = obj.id_vch_load.modulation
return par.name
modulation.short_description = "Модуляция"
def snr(self, obj):
par = obj.id_vch_load
return par.snr
snr.short_description = "ОСШ"
def geo_coords(self, obj):
geo = obj.id_geo
longitude = geo.coords.coords[0]
latitude = geo.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}"
geo_coords.short_description = "Координаты геолокации"
def kupsat_coords(self, obj):
obj = obj.id_geo
if obj.coords_kupsat is None:
return "-"
longitude = obj.coords_kupsat.coords[0]
latitude = obj.coords_kupsat.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}"
kupsat_coords.short_description = "Координаты Кубсата"
def valid_coords(self, obj):
obj = obj.id_geo
if obj.coords_valid is None:
return "-"
longitude = obj.coords_valid.coords[0]
latitude = obj.coords_valid.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}"
valid_coords.short_description = "Координаты оперативного отдела"