новый структура моделей
This commit is contained in:
@@ -23,6 +23,7 @@ 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 leaflet.forms.widgets import LeafletWidget
|
||||
|
||||
from rangefilter.filters import (
|
||||
DateRangeFilterBuilder,
|
||||
@@ -90,6 +91,28 @@ class LocationForm(forms.ModelForm):
|
||||
return instance
|
||||
|
||||
|
||||
class GeoInline(admin.StackedInline):
|
||||
model = Geo
|
||||
extra = 0
|
||||
verbose_name = "Гео"
|
||||
verbose_name_plural = "Гео"
|
||||
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"),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
class CustomUserInline(admin.StackedInline):
|
||||
@@ -130,7 +153,7 @@ class ModulationAdmin(admin.ModelAdmin):
|
||||
ordering = ("name",)
|
||||
|
||||
@admin.register(SourceType)
|
||||
class ModulationAdmin(admin.ModelAdmin):
|
||||
class SourceTypeAdmin(admin.ModelAdmin):
|
||||
list_display = ("name",)
|
||||
search_fields = ("name",)
|
||||
ordering = ("name",)
|
||||
@@ -200,6 +223,7 @@ class ParameterAdmin(ImportExportActionModelAdmin, admin.ModelAdmin):
|
||||
)
|
||||
ordering = ("frequency",)
|
||||
list_select_related = ("polarization", "modulation", "standard", "id_satellite",)
|
||||
filter_horizontal = ('objitems',) # For many-to-many relationship
|
||||
# raw_id_fields = ("id_sigma_parameter", )
|
||||
inlines = [SigmaParameterInline]
|
||||
# autocomplete_fields = ("id_sigma_parameter", )
|
||||
@@ -378,8 +402,44 @@ def show_on_map(modeladmin, request, queryset):
|
||||
|
||||
show_on_map.short_description = "Показать выбранные на карте"
|
||||
|
||||
class ObjItemForm(forms.ModelForm):
|
||||
parameter = forms.ModelChoiceField(
|
||||
queryset=Parameter.objects.all(),
|
||||
required=False,
|
||||
label="Параметр"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = ObjItem
|
||||
fields = '__all__'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Set initial value if the ObjItem already has a parameter
|
||||
if self.instance.pk:
|
||||
first_param = self.instance.parameters_obj.first()
|
||||
if first_param:
|
||||
self.fields['parameter'].initial = first_param
|
||||
|
||||
def save(self, commit=True):
|
||||
instance = super().save(commit=commit)
|
||||
|
||||
# Handle the single parameter assignment - replace all existing relationships
|
||||
if self.cleaned_data.get('parameter'):
|
||||
# Clear all existing parameter relationships
|
||||
instance.parameters_obj.clear()
|
||||
# Add the selected parameter
|
||||
instance.parameters_obj.add(self.cleaned_data['parameter'])
|
||||
else:
|
||||
# If no parameter selected, clear all
|
||||
instance.parameters_obj.clear()
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
@admin.register(ObjItem)
|
||||
class ObjectAdmin(admin.ModelAdmin):
|
||||
form = ObjItemForm
|
||||
list_display = (
|
||||
"name",
|
||||
"sat_name",
|
||||
@@ -399,121 +459,142 @@ class ObjectAdmin(admin.ModelAdmin):
|
||||
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),
|
||||
("parameters_obj__id_satellite", MultiSelectRelatedDropdownFilter),
|
||||
("parameters_obj__frequency", NumericRangeFilterBuilder()),
|
||||
("parameters_obj__freq_range", NumericRangeFilterBuilder()),
|
||||
("parameters_obj__snr", NumericRangeFilterBuilder()),
|
||||
("parameters_obj__modulation", MultiSelectRelatedDropdownFilter),
|
||||
("parameters_obj__polarization", MultiSelectRelatedDropdownFilter),
|
||||
GeoKupDistanceFilter,
|
||||
GeoValidDistanceFilter
|
||||
)
|
||||
search_fields = (
|
||||
"name",
|
||||
"id_geo__coords",
|
||||
# "id_satellite__name",
|
||||
# "id_vch_load__frequency",
|
||||
"geo_obj__coords",
|
||||
"parameters_obj__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",
|
||||
"id_source_type"
|
||||
)
|
||||
autocomplete_fields = ("id_geo",)
|
||||
raw_id_fields = ("id_vch_load",)
|
||||
# dynamic_raw_id_fields = ("id_vch_load",)
|
||||
inlines = [GeoInline]
|
||||
actions = [show_on_map]
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.select_related('geo_obj').prefetch_related(
|
||||
'parameters_obj__id_satellite',
|
||||
'parameters_obj__polarization',
|
||||
'parameters_obj__modulation',
|
||||
'parameters_obj__standard'
|
||||
)
|
||||
|
||||
def sat_name(self, obj):
|
||||
return obj.id_vch_load.id_satellite
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param and param.id_satellite:
|
||||
return param.id_satellite.name
|
||||
return "-"
|
||||
sat_name.short_description = "Спутник"
|
||||
sat_name.admin_order_field = "id_vch_load__id_satellite__name"
|
||||
sat_name.admin_order_field = "parameters_obj__id_satellite__name"
|
||||
|
||||
def freq(self, obj):
|
||||
par = obj.id_vch_load
|
||||
return par.frequency
|
||||
# param = obj.parameters_obj.first()
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param:
|
||||
return param.frequency
|
||||
return "-"
|
||||
freq.short_description = "Частота, МГц"
|
||||
freq.admin_order_field = "id_vch_load__frequency"
|
||||
freq.admin_order_field = "parameters_obj__frequency"
|
||||
|
||||
def distance_geo_kup(self, obj):
|
||||
par = obj.id_geo.distance_coords_kup
|
||||
if par is None:
|
||||
geo = obj.geo_obj
|
||||
if not geo or geo.distance_coords_kup is None:
|
||||
return "-"
|
||||
return round(par, 3)
|
||||
return round(geo.distance_coords_kup, 3)
|
||||
distance_geo_kup.short_description = "Гео-куб, км"
|
||||
|
||||
def distance_geo_valid(self, obj):
|
||||
par = obj.id_geo.distance_coords_valid
|
||||
if par is None:
|
||||
geo = obj.geo_obj
|
||||
if not geo or geo.distance_coords_valid is None:
|
||||
return "-"
|
||||
return round(par, 3)
|
||||
return round(geo.distance_coords_valid, 3)
|
||||
distance_geo_valid.short_description = "Гео-опер, км"
|
||||
|
||||
def distance_kup_valid(self, obj):
|
||||
par = obj.id_geo.distance_kup_valid
|
||||
if par is None:
|
||||
geo = obj.geo_obj
|
||||
if not geo or geo.distance_kup_valid is None:
|
||||
return "-"
|
||||
return round(par, 3)
|
||||
return round(geo.distance_kup_valid, 3)
|
||||
distance_kup_valid.short_description = "Куб-опер, км"
|
||||
|
||||
def pol(self, obj):
|
||||
par = obj.id_vch_load.polarization
|
||||
return par.name
|
||||
# Get the first parameter associated with this objitem to display polarization
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param and param.polarization:
|
||||
return param.polarization.name
|
||||
return "-"
|
||||
pol.short_description = "Поляризация"
|
||||
|
||||
def freq_range(self, obj):
|
||||
par = obj.id_vch_load
|
||||
return par.freq_range
|
||||
# Get the first parameter associated with this objitem to display freq_range
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param:
|
||||
return param.freq_range
|
||||
return "-"
|
||||
freq_range.short_description = "Полоса, МГц"
|
||||
freq_range.admin_order_field = "id_vch_load__freq_range"
|
||||
freq_range.admin_order_field = "parameters_obj__freq_range"
|
||||
|
||||
def bod_velocity(self, obj):
|
||||
par = obj.id_vch_load
|
||||
return par.bod_velocity
|
||||
# Get the first parameter associated with this objitem to display bod_velocity
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param:
|
||||
return param.bod_velocity
|
||||
return "-"
|
||||
bod_velocity.short_description = "Сим. v, БОД"
|
||||
|
||||
def modulation(self, obj):
|
||||
par = obj.id_vch_load.modulation
|
||||
return par.name
|
||||
# Get the first parameter associated with this objitem to display modulation
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param and param.modulation:
|
||||
return param.modulation.name
|
||||
return "-"
|
||||
modulation.short_description = "Модуляция"
|
||||
|
||||
def snr(self, obj):
|
||||
par = obj.id_vch_load
|
||||
return par.snr
|
||||
# Get the first parameter associated with this objitem to display snr
|
||||
param = next(iter(obj.parameters_obj.all()), None)
|
||||
if param:
|
||||
return param.snr
|
||||
return "-"
|
||||
snr.short_description = "ОСШ"
|
||||
|
||||
def geo_coords(self, obj):
|
||||
geo = obj.id_geo
|
||||
geo = obj.geo_obj
|
||||
if not geo or not geo.coords:
|
||||
return "-"
|
||||
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 = "Координаты геолокации"
|
||||
geo_coords.admin_order_filed = "id_geo__coords"
|
||||
geo_coords.admin_order_field = "geo_obj__coords"
|
||||
|
||||
def kupsat_coords(self, obj):
|
||||
obj = obj.id_geo
|
||||
if obj.coords_kupsat is None:
|
||||
geo = obj.geo_obj
|
||||
if not geo or not geo.coords_kupsat:
|
||||
return "-"
|
||||
longitude = obj.coords_kupsat.coords[0]
|
||||
latitude = obj.coords_kupsat.coords[1]
|
||||
longitude = geo.coords_kupsat.coords[0]
|
||||
latitude = geo.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:
|
||||
geo = obj.geo_obj
|
||||
if not geo or not geo.coords_valid:
|
||||
return "-"
|
||||
longitude = obj.coords_valid.coords[0]
|
||||
latitude = obj.coords_valid.coords[1]
|
||||
longitude = geo.coords_valid.coords[0]
|
||||
latitude = geo.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}"
|
||||
|
||||
Reference in New Issue
Block a user