init commit
This commit is contained in:
506
dbapp/mainapp/admin.py
Normal file
506
dbapp/mainapp/admin.py
Normal 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 = "Координаты оперативного отдела"
|
||||
Reference in New Issue
Block a user