Добавил объединение источников. Вернул норм карту. Удалил ненужные либы
This commit is contained in:
@@ -34,7 +34,7 @@ from .lyngsat import (
|
||||
ClearLyngsatCacheView,
|
||||
UnlinkAllLyngsatSourcesView,
|
||||
)
|
||||
from .source import SourceListView, SourceCreateView, SourceUpdateView, SourceDeleteView, DeleteSelectedSourcesView
|
||||
from .source import SourceListView, SourceCreateView, SourceUpdateView, SourceDeleteView, DeleteSelectedSourcesView, MergeSourcesView
|
||||
from .transponder import (
|
||||
TransponderListView,
|
||||
TransponderCreateView,
|
||||
@@ -53,7 +53,7 @@ from .map import (
|
||||
ShowSourcesMapView,
|
||||
ShowSourceWithPointsMapView,
|
||||
ShowSourceAveragingStepsMapView,
|
||||
ClusterTestView,
|
||||
# ClusterTestView,
|
||||
)
|
||||
from .kubsat import (
|
||||
KubsatView,
|
||||
@@ -101,6 +101,7 @@ __all__ = [
|
||||
'SourceUpdateView',
|
||||
'SourceDeleteView',
|
||||
'DeleteSelectedSourcesView',
|
||||
'MergeSourcesView',
|
||||
# Transponder
|
||||
'TransponderListView',
|
||||
'TransponderCreateView',
|
||||
@@ -117,7 +118,7 @@ __all__ = [
|
||||
'ShowSourcesMapView',
|
||||
'ShowSourceWithPointsMapView',
|
||||
'ShowSourceAveragingStepsMapView',
|
||||
'ClusterTestView',
|
||||
# 'ClusterTestView',
|
||||
# Kubsat
|
||||
'KubsatView',
|
||||
'KubsatExportView',
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.shortcuts import redirect, render
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
|
||||
from ..clusters import get_clusters
|
||||
# from ..clusters import get_clusters
|
||||
from ..mixins import RoleRequiredMixin
|
||||
from ..models import ObjItem
|
||||
|
||||
@@ -418,19 +418,19 @@ class ShowSourceAveragingStepsMapView(LoginRequiredMixin, View):
|
||||
return render(request, "mainapp/source_averaging_map.html", context)
|
||||
|
||||
|
||||
class ClusterTestView(LoginRequiredMixin, View):
|
||||
"""Test view for clustering functionality."""
|
||||
# class ClusterTestView(LoginRequiredMixin, View):
|
||||
# """Test view for clustering functionality."""
|
||||
|
||||
def get(self, request):
|
||||
objs = ObjItem.objects.filter(
|
||||
name__icontains="! Astra 4A 12654,040 [1,962] МГц H"
|
||||
)
|
||||
coords = []
|
||||
for obj in objs:
|
||||
if hasattr(obj, "geo_obj") and obj.geo_obj and obj.geo_obj.coords:
|
||||
coords.append(
|
||||
(obj.geo_obj.coords.coords[1], obj.geo_obj.coords.coords[0])
|
||||
)
|
||||
get_clusters(coords)
|
||||
# def get(self, request):
|
||||
# objs = ObjItem.objects.filter(
|
||||
# name__icontains="! Astra 4A 12654,040 [1,962] МГц H"
|
||||
# )
|
||||
# coords = []
|
||||
# for obj in objs:
|
||||
# if hasattr(obj, "geo_obj") and obj.geo_obj and obj.geo_obj.coords:
|
||||
# coords.append(
|
||||
# (obj.geo_obj.coords.coords[1], obj.geo_obj.coords.coords[0])
|
||||
# )
|
||||
# get_clusters(coords)
|
||||
|
||||
return JsonResponse({"success": "ок"})
|
||||
# return JsonResponse({"success": "ок"})
|
||||
|
||||
@@ -980,3 +980,120 @@ class DeleteSelectedSourcesView(LoginRequiredMixin, AdminModeratorMixin, View):
|
||||
|
||||
except Exception as e:
|
||||
return JsonResponse({"error": f"Ошибка при удалении: {str(e)}"}, status=500)
|
||||
|
||||
|
||||
|
||||
class MergeSourcesView(LoginRequiredMixin, AdminModeratorMixin, View):
|
||||
"""View for merging multiple sources into one."""
|
||||
|
||||
def post(self, request):
|
||||
"""Merge selected sources into the first one."""
|
||||
try:
|
||||
# Parse JSON body
|
||||
import json
|
||||
data = json.loads(request.body)
|
||||
|
||||
source_ids = data.get('source_ids', [])
|
||||
info_id = data.get('info_id')
|
||||
ownership_id = data.get('ownership_id')
|
||||
note = data.get('note', '')
|
||||
|
||||
# Validate input
|
||||
if not source_ids or len(source_ids) < 2:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Необходимо выбрать минимум 2 источника для объединения'
|
||||
}, status=400)
|
||||
|
||||
if not info_id:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Необходимо выбрать тип объекта'
|
||||
}, status=400)
|
||||
|
||||
if not ownership_id:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Необходимо выбрать принадлежность объекта'
|
||||
}, status=400)
|
||||
|
||||
# Get all sources
|
||||
sources = Source.objects.filter(id__in=source_ids).order_by('id')
|
||||
|
||||
if sources.count() != len(source_ids):
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Некоторые источники не найдены'
|
||||
}, status=404)
|
||||
|
||||
# First source is the target
|
||||
target_source = sources.first()
|
||||
sources_to_merge = sources.exclude(id=target_source.id)
|
||||
|
||||
# Get ObjectInfo and ObjectOwnership
|
||||
from ..models import ObjectInfo, ObjectOwnership
|
||||
try:
|
||||
info = ObjectInfo.objects.get(id=info_id)
|
||||
ownership = ObjectOwnership.objects.get(id=ownership_id)
|
||||
except (ObjectInfo.DoesNotExist, ObjectOwnership.DoesNotExist):
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Тип объекта или принадлежность не найдены'
|
||||
}, status=404)
|
||||
|
||||
# Start transaction
|
||||
from django.db import transaction
|
||||
|
||||
with transaction.atomic():
|
||||
# Update target source
|
||||
target_source.info = info
|
||||
target_source.ownership = ownership
|
||||
target_source.note = note
|
||||
if hasattr(request.user, 'customuser'):
|
||||
target_source.updated_by = request.user.customuser
|
||||
target_source.save()
|
||||
|
||||
# Move all ObjItems from sources_to_merge to target_source
|
||||
total_moved = 0
|
||||
for source in sources_to_merge:
|
||||
# Get all objitems for this source
|
||||
objitems = source.source_objitems.all()
|
||||
objitem_count = objitems.count()
|
||||
|
||||
# Update source field for all objitems
|
||||
objitems.update(source=target_source)
|
||||
|
||||
total_moved += objitem_count
|
||||
|
||||
# Recalculate coords_average for target source
|
||||
target_source._recalculate_average_coords()
|
||||
target_source.update_confirm_at()
|
||||
target_source.save()
|
||||
|
||||
# Delete sources_to_merge (without cascade deleting objitems since we moved them)
|
||||
# We need to delete marks first (they have CASCADE)
|
||||
from ..models import ObjectMark
|
||||
ObjectMark.objects.filter(source__in=sources_to_merge).delete()
|
||||
|
||||
# Now delete the sources
|
||||
deleted_count = sources_to_merge.count()
|
||||
sources_to_merge.delete()
|
||||
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
'message': f'Успешно объединено {deleted_count + 1} источников. Перемещено {total_moved} точек в источник #{target_source.id}',
|
||||
'target_source_id': target_source.id,
|
||||
'moved_objitems': total_moved,
|
||||
'deleted_sources': deleted_count
|
||||
})
|
||||
|
||||
except json.JSONDecodeError:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': 'Неверный формат данных'
|
||||
}, status=400)
|
||||
except Exception as e:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'error': f'Ошибка при объединении источников: {str(e)}'
|
||||
}, status=500)
|
||||
|
||||
Reference in New Issue
Block a user