Files
dbstorage/dbapp/mainapp/views.py

845 lines
34 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.shortcuts import render, redirect
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.views.decorators.http import require_GET
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views import View
from django.db.models import OuterRef, Subquery
from django.views.generic import TemplateView, FormView, UpdateView, DeleteView, CreateView
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.contrib.auth import logout
from django.forms import inlineformset_factory, modelformset_factory
from django.db import models
from django.urls import reverse_lazy
from django.contrib.gis.geos import Point
import pandas as pd
from .utils import (
fill_data_from_df,
add_satellite_list,
get_points_from_csv,
get_vch_load_from_html,
compare_and_link_vch_load,
kub_report
)
from mapsapp.utils import parse_transponders_from_json, parse_transponders_from_xml
from .forms import (
LoadExcelData,
LoadCsvData,
UploadFileForm,
VchLinkForm,
UploadVchLoad,
NewEventForm,
ObjItemForm,
ParameterForm,
GeoForm
)
from .models import ObjItem, Modulation, Polarization
from .clusters import get_clusters
from io import BytesIO
from datetime import datetime
class AddSatellitesView(LoginRequiredMixin, View):
def get(self, request):
add_satellite_list()
return redirect('home')
# class AddTranspondersView(View):
# def get(self, request):
# try:
# parse_transponders_from_json(BASE_DIR / "transponders.json")
# except FileNotFoundError:
# print("Файл не найден")
# return redirect('home')
class AddTranspondersView(LoginRequiredMixin, FormView):
template_name = 'mainapp/transponders_upload.html'
form_class = UploadFileForm
def form_valid(self, form):
uploaded_file = self.request.FILES['file']
try:
content = uploaded_file.read()
parse_transponders_from_xml(BytesIO(content))
messages.success(self.request, "Файл успешно обработан")
except ValueError as e:
messages.error(self.request, f"Ошибка при чтении таблиц: {e}")
except Exception as e:
messages.error(self.request, f"Неизвестная ошибка: {e}")
return redirect('add_trans')
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
from django.views.generic import View
class ActionsPageView(View):
def get(self, request):
if request.user.is_authenticated:
return render(request, 'mainapp/actions.html')
else:
return render(request, 'mainapp/login_required.html')
class HomePageView(View):
def get(self, request):
if request.user.is_authenticated:
# Redirect to objitem list if authenticated
return redirect('objitem_list')
else:
return render(request, 'mainapp/login_required.html')
class LoadExcelDataView(LoginRequiredMixin, FormView):
template_name = 'mainapp/add_data_from_excel.html'
form_class = LoadExcelData
def form_valid(self, form):
uploaded_file = self.request.FILES['file']
selected_sat = form.cleaned_data['sat_choice']
number = form.cleaned_data['number_input']
try:
import io
df = pd.read_excel(io.BytesIO(uploaded_file.read()))
if number > 0:
df = df.head(number)
result = fill_data_from_df(df, selected_sat, self.request.user.customuser)
messages.success(self.request, f"Данные успешно загружены! Обработано строк: {result}")
return redirect('load_excel_data')
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect('load_excel_data')
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
from django.views.generic import View
from django.core.paginator import Paginator
from django.db.models import Prefetch
from .models import Satellite, ObjItem, Parameter, Geo
class GetLocationsView(LoginRequiredMixin, View):
def get(self, request, 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.geo_obj.coords[0], loc.geo_obj.coords[1]]
},
"properties": {
"pol": param.polarization.name,
"freq": param.frequency*1000000,
"name": f"{loc.name}",
"id": loc.geo_obj.id
}
})
return JsonResponse({
"type": "FeatureCollection",
"features": features
})
class LoadCsvDataView(LoginRequiredMixin, FormView):
template_name = 'mainapp/add_data_from_csv.html'
form_class = LoadCsvData
def form_valid(self, form):
uploaded_file = self.request.FILES['file']
try:
# Read the file content and pass it directly to the function
content = uploaded_file.read()
if isinstance(content, bytes):
content = content.decode('utf-8')
get_points_from_csv(content, self.request.user.customuser)
messages.success(self.request, f"Данные успешно загружены!")
return redirect('load_csv_data')
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect('load_csv_data')
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
from collections import defaultdict
@method_decorator(staff_member_required, name='dispatch')
class ShowMapView(UserPassesTestMixin, View):
def test_func(self):
return self.request.user.is_staff
def get(self, request):
ids = request.GET.get('ids', '')
points = []
if ids:
id_list = [int(x) for x in ids.split(',') if x.isdigit()]
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"{param.frequency} [{param.freq_range}] МГц",
'point': (obj.geo_obj.coords.x, obj.geo_obj.coords.y)
})
else:
return redirect('admin')
grouped = defaultdict(list)
for p in points:
grouped[p["name"]].append({
'point': p["point"],
'frequency': p["freq"]
})
groups = [
{
"name": name,
"points": coords_list
}
for name, coords_list in grouped.items()
]
context = {
'groups': groups,
}
return render(request, 'admin/map_custom.html', context)
class ClusterTestView(LoginRequiredMixin, View):
def get(self, request):
objs = ObjItem.objects.filter(name__icontains="! Astra 4A 12654,040 [1,962] МГц H")
coords = []
for obj in objs:
if 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": "ок"})
def custom_logout(request):
logout(request)
return redirect('home')
class UploadVchLoadView(LoginRequiredMixin, FormView):
template_name = 'mainapp/upload_html.html'
form_class = UploadVchLoad
def form_valid(self, form):
selected_sat = form.cleaned_data['sat_choice']
uploaded_file = self.request.FILES['file']
try:
get_vch_load_from_html(uploaded_file, selected_sat)
messages.success(self.request, "Файл успешно обработан")
except ValueError as e:
messages.error(self.request, f"Ошибка при чтении таблиц: {e}")
except Exception as e:
messages.error(self.request, f"Неизвестная ошибка: {e}")
return redirect('vch_load')
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
class LinkVchSigmaView(LoginRequiredMixin, FormView):
template_name = 'mainapp/link_vch.html'
form_class = VchLinkForm
def form_valid(self, form):
freq = form.cleaned_data['value1']
freq_range = form.cleaned_data['value2']
# 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, 1)
messages.success(self.request, f"Привязано {link_count} из {count_all} объектов")
return redirect('link_vch_sigma')
def form_invalid(self, form):
return self.render_to_response(self.get_context_data(form=form))
class ProcessKubsatView(LoginRequiredMixin, FormView):
template_name = 'mainapp/process_kubsat.html'
form_class = NewEventForm
def form_valid(self, form):
# selected_sat = form.cleaned_data['sat_choice']
# selected_pol = form.cleaned_data['pol_choice']
uploaded_file = self.request.FILES['file']
try:
content = uploaded_file.read()
df = kub_report(BytesIO(content))
output = BytesIO()
with pd.ExcelWriter(output, engine='openpyxl') as writer:
df.to_excel(writer, index=False, sheet_name='Результат')
output.seek(0)
response = HttpResponse(
output.getvalue(),
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response['Content-Disposition'] = f'attachment; filename="kubsat_report.xlsx"'
messages.success(self.request, "Событие успешно обработано!")
return response
except Exception as e:
messages.error(self.request, f"Ошибка при обработке файла: {str(e)}")
return redirect('kubsat_excel')
# return redirect('kubsat_excel')
def form_invalid(self, form):
messages.error(self.request, "Форма заполнена некорректно.")
return super().form_invalid(form)
from django.contrib.auth.mixins import LoginRequiredMixin
class ObjItemListView(LoginRequiredMixin, View):
def get(self, request):
satellites = Satellite.objects.filter(parameters__objitems__isnull=False).distinct().order_by('name')
selected_sat_id = request.GET.get('satellite_id')
page_number = request.GET.get('page', 1)
items_per_page = request.GET.get('items_per_page', '50')
sort_param = request.GET.get('sort', '')
freq_min = request.GET.get('freq_min')
freq_max = request.GET.get('freq_max')
range_min = request.GET.get('range_min')
range_max = request.GET.get('range_max')
snr_min = request.GET.get('snr_min')
snr_max = request.GET.get('snr_max')
bod_min = request.GET.get('bod_min')
bod_max = request.GET.get('bod_max')
search_query = request.GET.get('search')
selected_modulations = request.GET.getlist('modulation')
selected_polarizations = request.GET.getlist('polarization')
selected_satellites = request.GET.getlist('satellite_id')
has_kupsat = request.GET.get('has_kupsat')
has_valid = request.GET.get('has_valid')
try:
items_per_page = int(items_per_page)
except ValueError:
items_per_page = 50
objects = ObjItem.objects.none()
if selected_satellites or selected_sat_id:
if selected_sat_id and not selected_satellites:
try:
selected_sat_id_single = int(selected_sat_id)
selected_satellites = [selected_sat_id_single]
except ValueError:
selected_satellites = []
if selected_satellites:
objects = ObjItem.objects.select_related(
'geo_obj',
'updated_by__user',
'created_by__user',
).prefetch_related(
'parameters_obj__id_satellite',
'parameters_obj__polarization',
'parameters_obj__modulation',
'parameters_obj__standard'
).filter(parameters_obj__id_satellite_id__in=selected_satellites)
else:
objects = ObjItem.objects.select_related(
'geo_obj',
'updated_by__user',
'created_by__user',
).prefetch_related(
'parameters_obj__id_satellite',
'parameters_obj__polarization',
'parameters_obj__modulation',
'parameters_obj__standard'
)
if freq_min is not None and freq_min.strip() != '':
try:
freq_min_val = float(freq_min)
objects = objects.filter(parameters_obj__frequency__gte=freq_min_val)
except ValueError:
pass
if freq_max is not None and freq_max.strip() != '':
try:
freq_max_val = float(freq_max)
objects = objects.filter(parameters_obj__frequency__lte=freq_max_val)
except ValueError:
pass
if range_min is not None and range_min.strip() != '':
try:
range_min_val = float(range_min)
objects = objects.filter(parameters_obj__freq_range__gte=range_min_val)
except ValueError:
pass
if range_max is not None and range_max.strip() != '':
try:
range_max_val = float(range_max)
objects = objects.filter(parameters_obj__freq_range__lte=range_max_val)
except ValueError:
pass
if snr_min is not None and snr_min.strip() != '':
try:
snr_min_val = float(snr_min)
objects = objects.filter(parameters_obj__snr__gte=snr_min_val)
except ValueError:
pass
if snr_max is not None and snr_max.strip() != '':
try:
snr_max_val = float(snr_max)
objects = objects.filter(parameters_obj__snr__lte=snr_max_val)
except ValueError:
pass
if bod_min is not None and bod_min.strip() != '':
try:
bod_min_val = float(bod_min)
objects = objects.filter(parameters_obj__bod_velocity__gte=bod_min_val)
except ValueError:
pass
if bod_max is not None and bod_max.strip() != '':
try:
bod_max_val = float(bod_max)
objects = objects.filter(parameters_obj__bod_velocity__lte=bod_max_val)
except ValueError:
pass
if selected_modulations:
objects = objects.filter(parameters_obj__modulation__id__in=selected_modulations)
if selected_polarizations:
objects = objects.filter(parameters_obj__polarization__id__in=selected_polarizations)
if has_kupsat == '1':
objects = objects.filter(geo_obj__coords_kupsat__isnull=False)
elif has_kupsat == '0':
objects = objects.filter(geo_obj__coords_kupsat__isnull=True)
if has_valid == '1':
objects = objects.filter(geo_obj__coords_valid__isnull=False)
elif has_valid == '0':
objects = objects.filter(geo_obj__coords_valid__isnull=True)
if search_query:
search_query = search_query.strip()
if search_query:
objects = objects.filter(
models.Q(name__icontains=search_query) |
models.Q(geo_obj__location__icontains=search_query)
)
else:
selected_sat_id = None
first_param_freq_subq = self.get_first_param_subquery('frequency')
first_param_range_subq = self.get_first_param_subquery('freq_range')
first_param_snr_subq = self.get_first_param_subquery('snr')
first_param_bod_subq = self.get_first_param_subquery('bod_velocity')
first_param_sat_name_subq = self.get_first_param_subquery('id_satellite__name')
first_param_pol_name_subq = self.get_first_param_subquery('polarization__name')
first_param_mod_name_subq = self.get_first_param_subquery('modulation__name')
objects = objects.annotate(
first_param_freq=Subquery(first_param_freq_subq),
first_param_range=Subquery(first_param_range_subq),
first_param_snr=Subquery(first_param_snr_subq),
first_param_bod=Subquery(first_param_bod_subq),
first_param_sat_name=Subquery(first_param_sat_name_subq),
first_param_pol_name=Subquery(first_param_pol_name_subq),
first_param_mod_name=Subquery(first_param_mod_name_subq),
)
valid_sort_fields = {
'name': 'name',
'-name': '-name',
'updated_at': 'updated_at',
'-updated_at': '-updated_at',
'created_at': 'created_at',
'-created_at': '-created_at',
'updated_by': 'updated_by__user__username',
'-updated_by': '-updated_by__user__username',
'created_by': 'created_by__user__username',
'-created_by': '-created_by__user__username',
'geo_timestamp': 'geo_obj__timestamp',
'-geo_timestamp': '-geo_obj__timestamp',
'frequency': 'first_param_freq',
'-frequency': '-first_param_freq',
'freq_range': 'first_param_range',
'-freq_range': '-first_param_range',
'snr': 'first_param_snr',
'-snr': '-first_param_snr',
'bod_velocity': 'first_param_bod',
'-bod_velocity': '-first_param_bod',
'satellite': 'first_param_sat_name',
'-satellite': '-first_param_sat_name',
'polarization': 'first_param_pol_name',
'-polarization': '-first_param_pol_name',
'modulation': 'first_param_mod_name',
'-modulation': '-first_param_mod_name',
}
if sort_param in valid_sort_fields:
objects = objects.order_by(valid_sort_fields[sort_param])
paginator = Paginator(objects, items_per_page)
page_obj = paginator.get_page(page_number)
processed_objects = []
for obj in page_obj:
param = None
if hasattr(obj, 'parameters_obj') and obj.parameters_obj.all():
param_list = list(obj.parameters_obj.all())
if param_list:
param = param_list[0]
geo_coords = "-"
kupsat_coords = "-"
valid_coords = "-"
distance_geo_kup = "-"
distance_geo_valid = "-"
distance_kup_valid = "-"
if obj.geo_obj:
geo_timestamp = obj.geo_obj.timestamp
if obj.geo_obj.coords:
longitude = obj.geo_obj.coords.coords[0]
latitude = obj.geo_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"
geo_coords = f"{lat} {lon}"
if obj.geo_obj.coords_kupsat:
longitude = obj.geo_obj.coords_kupsat.coords[0]
latitude = obj.geo_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"
kupsat_coords = f"{lat} {lon}"
elif obj.geo_obj.coords_kupsat is not None:
kupsat_coords = "-"
if obj.geo_obj.coords_valid:
longitude = obj.geo_obj.coords_valid.coords[0]
latitude = obj.geo_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"
valid_coords = f"{lat} {lon}"
elif obj.geo_obj.coords_valid is not None:
valid_coords = "-"
if obj.geo_obj.distance_coords_kup is not None:
distance_geo_kup = f"{obj.geo_obj.distance_coords_kup:.3f}"
if obj.geo_obj.distance_coords_valid is not None:
distance_geo_valid = f"{obj.geo_obj.distance_coords_valid:.3f}"
if obj.geo_obj.distance_kup_valid is not None:
distance_kup_valid = f"{obj.geo_obj.distance_kup_valid:.3f}"
satellite_name = "-"
frequency = "-"
freq_range = "-"
polarization_name = "-"
bod_velocity = "-"
modulation_name = "-"
snr = "-"
if param:
if hasattr(param, 'id_satellite') and param.id_satellite:
satellite_name = param.id_satellite.name if hasattr(param.id_satellite, 'name') else "-"
frequency = f"{param.frequency:.3f}" if param.frequency is not None else "-"
freq_range = f"{param.freq_range:.3f}" if param.freq_range is not None else "-"
bod_velocity = f"{param.bod_velocity:.0f}" if param.bod_velocity is not None else "-"
snr = f"{param.snr:.0f}" if param.snr is not None else "-"
if hasattr(param, 'polarization') and param.polarization:
polarization_name = param.polarization.name if hasattr(param.polarization, 'name') else "-"
if hasattr(param, 'modulation') and param.modulation:
modulation_name = param.modulation.name if hasattr(param.modulation, 'name') else "-"
processed_objects.append({
'id': obj.id,
'name': obj.name or "-",
'satellite_name': satellite_name,
'frequency': frequency,
'freq_range': freq_range,
'polarization': polarization_name,
'bod_velocity': bod_velocity,
'modulation': modulation_name,
'snr': snr,
'geo_timestamp': geo_timestamp,
'geo_coords': geo_coords,
'kupsat_coords': kupsat_coords,
'valid_coords': valid_coords,
'distance_geo_kup': distance_geo_kup,
'distance_geo_valid': distance_geo_valid,
'distance_kup_valid': distance_kup_valid,
'updated_by': obj.updated_by if obj.updated_by else '-',
'obj': obj
})
modulations = Modulation.objects.all()
polarizations = Polarization.objects.all()
context = {
'satellites': satellites,
'selected_satellite_id': selected_sat_id,
'page_obj': page_obj,
'processed_objects': processed_objects,
'items_per_page': items_per_page,
'available_items_per_page': [50, 100, 500, 1000],
'freq_min': freq_min,
'freq_max': freq_max,
'range_min': range_min,
'range_max': range_max,
'snr_min': snr_min,
'snr_max': snr_max,
'bod_min': bod_min,
'bod_max': bod_max,
'search_query': search_query,
'selected_modulations': [int(x) for x in selected_modulations if x.isdigit()],
'selected_polarizations': [int(x) for x in selected_polarizations if x.isdigit()],
'selected_satellites': [int(x) for x in selected_satellites if x.isdigit()],
'has_kupsat': has_kupsat,
'has_valid': has_valid,
'modulations': modulations,
'polarizations': polarizations,
'full_width_page': True,
'sort': sort_param,
}
return render(request, 'mainapp/objitem_list.html', context)
def get_first_param_subquery(self, field_name):
return Parameter.objects.filter(
objitems=OuterRef('pk')
).order_by('id').values(field_name)[:1]
class ObjItemUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = ObjItem
form_class = ObjItemForm
template_name = 'mainapp/objitem_form.html'
success_url = reverse_lazy('home')
def test_func(self):
return self.request.user.customuser.role in ['admin', 'moderator']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['LEAFLET_CONFIG'] = {
'DEFAULT_CENTER': (55.75, 37.62),
'DEFAULT_ZOOM': 5,
}
ParameterFormSet = modelformset_factory(
Parameter,
form=ParameterForm,
extra=0,
can_delete=True
)
if self.object:
parameter_queryset = self.object.parameters_obj.all()
context['parameter_forms'] = ParameterFormSet(
queryset=parameter_queryset,
prefix='parameters'
)
if hasattr(self.object, 'geo_obj'):
context['geo_form'] = GeoForm(instance=self.object.geo_obj, prefix='geo')
else:
context['geo_form'] = GeoForm(prefix='geo')
else:
context['parameter_forms'] = ParameterFormSet(
queryset=Parameter.objects.none(),
prefix='parameters'
)
context['geo_form'] = GeoForm(prefix='geo')
return context
def form_valid(self, form):
context = self.get_context_data()
parameter_forms = context['parameter_forms']
geo_form = context['geo_form']
# Сохраняем основной объект
self.object = form.save(commit=False)
self.object.updated_by = self.request.user.customuser
self.object.save()
# Сохраняем связанные параметры
if parameter_forms.is_valid():
instances = parameter_forms.save(commit=False)
for instance in instances:
instance.save()
instance.objitems.set([self.object])
# Сохраняем геоданные
geo_instance = None
if hasattr(self.object, 'geo_obj'):
geo_instance = self.object.geo_obj
# Создаем или обновляем гео-объект
if geo_instance is None:
geo_instance = Geo(objitem=self.object)
# Обновляем поля из geo_form
if geo_form.is_valid():
geo_instance.location = geo_form.cleaned_data['location']
geo_instance.comment = geo_form.cleaned_data['comment']
geo_instance.is_average = geo_form.cleaned_data['is_average']
# Обрабатываем координаты геолокации
geo_longitude = self.request.POST.get('geo_longitude')
geo_latitude = self.request.POST.get('geo_latitude')
if geo_longitude and geo_latitude:
geo_instance.coords = Point(float(geo_longitude), float(geo_latitude), srid=4326)
# Обрабатываем координаты Кубсата
kupsat_longitude = self.request.POST.get('kupsat_longitude')
kupsat_latitude = self.request.POST.get('kupsat_latitude')
if kupsat_longitude and kupsat_latitude:
geo_instance.coords_kupsat = Point(float(kupsat_longitude), float(kupsat_latitude), srid=4326)
# Обрабатываем координаты оперативников
valid_longitude = self.request.POST.get('valid_longitude')
valid_latitude = self.request.POST.get('valid_latitude')
if valid_longitude and valid_latitude:
geo_instance.coords_valid = Point(float(valid_longitude), float(valid_latitude), srid=4326)
# Обрабатываем дату/время
timestamp_date = self.request.POST.get('timestamp_date')
timestamp_time = self.request.POST.get('timestamp_time')
if timestamp_date and timestamp_time:
naive_datetime = datetime.strptime(f"{timestamp_date} {timestamp_time}", "%Y-%m-%d %H:%M")
geo_instance.timestamp = naive_datetime
geo_instance.save()
messages.success(self.request, 'Объект успешно сохранён!')
return super().form_valid(form)
class ObjItemCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = ObjItem
form_class = ObjItemForm
template_name = 'mainapp/objitem_form.html'
success_url = reverse_lazy('home')
def test_func(self):
return self.request.user.customuser.role in ['admin', 'moderator']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
ParameterFormSet = modelformset_factory(
Parameter,
form=ParameterForm,
extra=1,
can_delete=True
)
context['parameter_forms'] = ParameterFormSet(
queryset=Parameter.objects.none(),
prefix='parameters'
)
context['geo_form'] = GeoForm(prefix='geo')
return context
def form_valid(self, form):
context = self.get_context_data()
parameter_forms = context['parameter_forms']
geo_form = context['geo_form']
# Сохраняем основной объект
self.object = form.save(commit=False)
self.object.created_by = self.request.user.customuser
self.object.updated_by = self.request.user.customuser
self.object.save()
# Сохраняем связанные параметры
if parameter_forms.is_valid():
instances = parameter_forms.save(commit=False)
for instance in instances:
instance.save()
instance.objitems.add(self.object)
# Создаем гео-объект
geo_instance = Geo(objitem=self.object)
# Обновляем поля из geo_form
if geo_form.is_valid():
geo_instance.location = geo_form.cleaned_data['location']
geo_instance.comment = geo_form.cleaned_data['comment']
geo_instance.is_average = geo_form.cleaned_data['is_average']
# Обрабатываем координаты геолокации
geo_longitude = self.request.POST.get('geo_longitude')
geo_latitude = self.request.POST.get('geo_latitude')
if geo_longitude and geo_latitude:
geo_instance.coords = Point(float(geo_longitude), float(geo_latitude), srid=4326)
# Обрабатываем координаты Кубсата
kupsat_longitude = self.request.POST.get('kupsat_longitude')
kupsat_latitude = self.request.POST.get('kupsat_latitude')
if kupsat_longitude and kupsat_latitude:
geo_instance.coords_kupsat = Point(float(kupsat_longitude), float(kupsat_latitude), srid=4326)
# Обрабатываем координаты оперативников
valid_longitude = self.request.POST.get('valid_longitude')
valid_latitude = self.request.POST.get('valid_latitude')
if valid_longitude and valid_latitude:
geo_instance.coords_valid = Point(float(valid_longitude), float(valid_latitude), srid=4326)
# Обрабатываем дату/время
timestamp_date = self.request.POST.get('timestamp_date')
timestamp_time = self.request.POST.get('timestamp_time')
if timestamp_date and timestamp_time:
naive_datetime = datetime.strptime(f"{timestamp_date} {timestamp_time}", "%Y-%m-%d %H:%M")
geo_instance.timestamp = naive_datetime
geo_instance.save()
messages.success(self.request, 'Объект успешно создан!')
return super().form_valid(form)
class ObjItemDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = ObjItem
template_name = 'mainapp/objitem_confirm_delete.html'
success_url = reverse_lazy('home')
def test_func(self):
return self.request.user.customuser.role in ['admin', 'moderator']
def delete(self, request, *args, **kwargs):
messages.success(self.request, 'Объект успешно удалён!')
return super().delete(request, *args, **kwargs)