rework objitem model
This commit is contained in:
@@ -98,6 +98,8 @@ class GeoInline(admin.StackedInline):
|
||||
verbose_name_plural = "Гео"
|
||||
form = LocationForm
|
||||
readonly_fields = ("distance_coords_kup", "distance_coords_valid", "distance_kup_valid")
|
||||
prefetch_related = ("mirrors",)
|
||||
autocomplete_fields = ('mirrors',)
|
||||
fieldsets = (
|
||||
("Основная информация", {
|
||||
"fields": ("mirrors", "location", "distance_coords_kup",
|
||||
@@ -223,7 +225,7 @@ class ParameterAdmin(ImportExportActionModelAdmin, admin.ModelAdmin):
|
||||
)
|
||||
ordering = ("frequency",)
|
||||
list_select_related = ("polarization", "modulation", "standard", "id_satellite",)
|
||||
filter_horizontal = ('objitems',) # For many-to-many relationship
|
||||
autocomplete_fields = ('objitems',)
|
||||
# raw_id_fields = ("id_sigma_parameter", )
|
||||
inlines = [SigmaParameterInline]
|
||||
# autocomplete_fields = ("id_sigma_parameter", )
|
||||
@@ -402,44 +404,17 @@ 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
|
||||
class ParameterObjItemInline(admin.StackedInline):
|
||||
model = ObjItem.parameters_obj.through
|
||||
extra = 0
|
||||
max_num = 1
|
||||
verbose_name = "ВЧ загрузка"
|
||||
verbose_name_plural = "ВЧ загрузки"
|
||||
|
||||
|
||||
|
||||
@admin.register(ObjItem)
|
||||
class ObjectAdmin(admin.ModelAdmin):
|
||||
form = ObjItemForm
|
||||
list_display = (
|
||||
"name",
|
||||
"sat_name",
|
||||
@@ -475,9 +450,11 @@ class ObjectAdmin(admin.ModelAdmin):
|
||||
)
|
||||
|
||||
ordering = ("name",)
|
||||
inlines = [GeoInline]
|
||||
inlines = [ParameterObjItemInline, GeoInline]
|
||||
actions = [show_on_map]
|
||||
|
||||
|
||||
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.select_related('geo_obj').prefetch_related(
|
||||
|
||||
@@ -60,12 +60,12 @@ class VchLinkForm(forms.Form):
|
||||
'class': 'form-select'
|
||||
})
|
||||
)
|
||||
ku_range = forms.ChoiceField(
|
||||
choices=[(9750.0, '9750'), (10750.0, '10750')],
|
||||
# coerce=lambda x: x == 'True',
|
||||
widget=forms.Select(attrs={'class': 'form-select'}),
|
||||
label='Выбор диапазона'
|
||||
)
|
||||
# ku_range = forms.ChoiceField(
|
||||
# choices=[(9750.0, '9750'), (10750.0, '10750')],
|
||||
# # coerce=lambda x: x == 'True',
|
||||
# widget=forms.Select(attrs={'class': 'form-select'}),
|
||||
# label='Выбор диапазона'
|
||||
# )
|
||||
value1 = forms.FloatField(
|
||||
label="Первое число",
|
||||
widget=forms.NumberInput(attrs={
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<p class="card-text">Введите допустимый разброс для частоты и полосы(в кГц)</p>
|
||||
<p class="card-text">Введите допустимый разброс для частоты и полосы</p>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
@@ -39,7 +39,7 @@
|
||||
{% endif %}
|
||||
</div> {% endcomment %}
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.value1.id_for_label }}" class="form-label">Разброс по частоте(в %)</label>
|
||||
<label for="{{ form.value1.id_for_label }}" class="form-label">Разброс по частоте(в МГц)</label>
|
||||
{{ form.value1 }}
|
||||
{% if form.value1.errors %}
|
||||
<div class="text-danger mt-1">{{ form.value1.errors }}</div>
|
||||
|
||||
@@ -143,19 +143,14 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite):
|
||||
geo_obj=geo
|
||||
)
|
||||
if not existing_obj_items.exists():
|
||||
# Такой объект уже существует, используем его
|
||||
# obj_item = existing_obj_items.first()
|
||||
obj_item = ObjItem.objects.create(
|
||||
name=source,
|
||||
id_user_add=CustomUser.objects.get(id=1)
|
||||
)
|
||||
# Устанавливаем связь с параметром
|
||||
obj_item.parameters_obj.set([vch_load_obj])
|
||||
# Устанавливаем связь с geo
|
||||
geo.objitem = obj_item
|
||||
geo.save()
|
||||
# else:
|
||||
# Создаем новый ObjItem
|
||||
|
||||
|
||||
# obj_item, _ = ObjItem.objects.get_or_create(
|
||||
@@ -280,16 +275,18 @@ def get_points_from_csv(file_content):
|
||||
)
|
||||
geo_obj.mirrors.set(Mirror.objects.filter(name__in=mir_lst))
|
||||
|
||||
obj_item_obj, _ = ObjItem.objects.get_or_create(
|
||||
name=row['obj'],
|
||||
# id_satellite=sat_obj,
|
||||
id_vch_load=vch_load_obj,
|
||||
id_geo=geo_obj,
|
||||
defaults={
|
||||
'id_user_add': CustomUser.objects.get(id=1)
|
||||
}
|
||||
existing_obj_items = ObjItem.objects.filter(
|
||||
parameters_obj=vch_load_obj,
|
||||
geo_obj=geo_obj
|
||||
)
|
||||
obj_item_obj.save()
|
||||
if not existing_obj_items.exists():
|
||||
obj_item = ObjItem.objects.create(
|
||||
name=row['obj'],
|
||||
id_user_add=CustomUser.objects.get(id=1)
|
||||
)
|
||||
obj_item.parameters_obj.set([vch_load_obj])
|
||||
geo_obj.objitem = obj_item
|
||||
geo_obj.save()
|
||||
|
||||
def get_vch_load_from_html(file, sat: Satellite) -> None:
|
||||
filename = file.name.split('_')
|
||||
@@ -367,18 +364,17 @@ def get_vch_load_from_html(file, sat: Satellite) -> None:
|
||||
sigma_load.save()
|
||||
|
||||
def compare_and_link_vch_load(sat_id: Satellite, eps_freq: float, eps_frange: float, ku_range: float):
|
||||
item_obj = ObjItem.objects.filter(id_vch_load__id_satellite=sat_id)
|
||||
item_obj = ObjItem.objects.filter(parameters_obj__id_satellite=sat_id)
|
||||
vch_sigma = SigmaParameter.objects.filter(id_satellite=sat_id)
|
||||
link_count = 0
|
||||
obj_count = len(item_obj)
|
||||
for idx, obj in enumerate(item_obj):
|
||||
vch_load = obj.id_vch_load
|
||||
vch_load = obj.parameters_obj.get()
|
||||
if vch_load.frequency == -1.0:
|
||||
continue
|
||||
# if unique_points = Point.objects.order_by('frequency').distinct('frequency')
|
||||
for sigma in vch_sigma:
|
||||
if (
|
||||
abs(sigma.transfer_frequency - vch_load.frequency) <= vch_load.frequency*eps_freq/100 and
|
||||
abs(sigma.transfer_frequency - vch_load.frequency) <= eps_freq and
|
||||
abs(sigma.freq_range - vch_load.freq_range) <= vch_load.freq_range*eps_frange/100 and
|
||||
sigma.polarization == vch_load.polarization
|
||||
):
|
||||
@@ -395,11 +391,18 @@ def kub_report(data_in: io.StringIO) -> pd.DataFrame:
|
||||
for row in df_in.iterrows():
|
||||
value = row[1]
|
||||
date = datetime.date(datetime.now())
|
||||
lat = value['Широта, град']
|
||||
lon = value['Долгота, град']
|
||||
isz = value['ИСЗ']
|
||||
downlink = value['Обратный канал, МГц']
|
||||
freq_range = value['Полоса, МГц']
|
||||
try:
|
||||
lat = float(value['Широта, град'].strip().replace(',', '.'))
|
||||
lon = float(value['Долгота, град'].strip().replace(',', '.'))
|
||||
downlink = float(value['Обратный канал, МГц'].strip().replace(',', '.'))
|
||||
freq_range = float(value['Полоса, МГц'].strip().replace(',', '.'))
|
||||
except Exception as e:
|
||||
lat = value['Широта, град']
|
||||
lon = value['Долгота, град']
|
||||
downlink = value['Обратный канал, МГц']
|
||||
freq_range = value['Полоса, МГц']
|
||||
print(e)
|
||||
norad = int(re.findall(r'\((\d+)\)', isz)[0])
|
||||
sat_obj = Satellite.objects.get(norad=norad)
|
||||
pol_obj = Polarization.objects.get(name=value['Поляризация'].strip())
|
||||
|
||||
@@ -92,23 +92,24 @@ from django.views.generic import View
|
||||
|
||||
class GetLocationsView(View):
|
||||
def get(self, request, sat_id):
|
||||
locations = ObjItem.objects.filter(id_vch_load__id_satellite=sat_id)
|
||||
locations = ObjItem.objects.filter(parameters_obj__id_satellite=sat_id)
|
||||
if not locations:
|
||||
return JsonResponse({'error': 'Объектов не найдено'}, status=400)
|
||||
|
||||
features = []
|
||||
for loc in locations:
|
||||
param = loc.parameters_obj.get()
|
||||
features.append({
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [loc.id_geo.coords[0], loc.id_geo.coords[1]]
|
||||
"coordinates": [loc.geo_obj.coords[0], loc.geo_obj.coords[1]]
|
||||
},
|
||||
"properties": {
|
||||
"pol": loc.id_vch_load.polarization.name,
|
||||
"freq": loc.id_vch_load.frequency*1000000,
|
||||
"pol": param.polarization.name,
|
||||
"freq": param.frequency*1000000,
|
||||
"name": f"{loc.name}",
|
||||
"id": loc.id_geo.id
|
||||
"id": loc.geo_obj.id
|
||||
}
|
||||
})
|
||||
|
||||
@@ -153,12 +154,19 @@ class ShowMapView(UserPassesTestMixin, View):
|
||||
points = []
|
||||
if ids:
|
||||
id_list = [int(x) for x in ids.split(',') if x.isdigit()]
|
||||
locations = ObjItem.objects.filter(id__in=id_list)
|
||||
locations = ObjItem.objects.filter(id__in=id_list).prefetch_related(
|
||||
'parameters_obj__id_satellite',
|
||||
'parameters_obj__polarization',
|
||||
'parameters_obj__modulation',
|
||||
'parameters_obj__standard',
|
||||
'geo_obj'
|
||||
)
|
||||
for obj in locations:
|
||||
param = obj.parameters_obj.get()
|
||||
points.append({
|
||||
'name': f"{obj.name}",
|
||||
'freq': f"{obj.id_vch_load.frequency} [{obj.id_vch_load.freq_range}] МГц",
|
||||
'point': (obj.id_geo.coords.x, obj.id_geo.coords.y)
|
||||
'freq': f"{param.frequency} [{param.freq_range}] МГц",
|
||||
'point': (obj.geo_obj.coords.x, obj.geo_obj.coords.y)
|
||||
})
|
||||
else:
|
||||
return redirect('admin')
|
||||
@@ -222,10 +230,10 @@ class LinkVchSigmaView(FormView):
|
||||
def form_valid(self, form):
|
||||
freq = form.cleaned_data['value1']
|
||||
freq_range = form.cleaned_data['value2']
|
||||
ku_range = float(form.cleaned_data['ku_range'])
|
||||
# ku_range = float(form.cleaned_data['ku_range'])
|
||||
sat_id = form.cleaned_data['sat_choice']
|
||||
# print(freq, freq_range, ku_range, sat_id.pk)
|
||||
count_all, link_count = compare_and_link_vch_load(sat_id, freq, freq_range, ku_range)
|
||||
count_all, link_count = compare_and_link_vch_load(sat_id, freq, freq_range, 1)
|
||||
messages.success(self.request, f"Привязано {link_count} из {count_all} объектов")
|
||||
return redirect('link_vch_sigma')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user