667 lines
26 KiB
Python
667 lines
26 KiB
Python
"""
|
||
ObjItem CRUD operations and related views.
|
||
"""
|
||
from django.contrib import messages
|
||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||
from django.core.paginator import Paginator
|
||
from django.db import models
|
||
from django.db.models import F
|
||
from django.http import JsonResponse
|
||
from django.shortcuts import redirect, render
|
||
from django.urls import reverse_lazy
|
||
from django.views import View
|
||
from django.views.generic import CreateView, DeleteView, UpdateView
|
||
|
||
from ..forms import GeoForm, ObjItemForm, ParameterForm
|
||
from ..mixins import CoordinateProcessingMixin, FormMessageMixin, RoleRequiredMixin
|
||
from ..models import Geo, Modulation, ObjItem, Polarization, Satellite
|
||
from ..utils import parse_pagination_params
|
||
|
||
|
||
class DeleteSelectedObjectsView(RoleRequiredMixin, View):
|
||
"""View for deleting multiple selected objects."""
|
||
|
||
required_roles = ["admin", "moderator"]
|
||
|
||
def post(self, request):
|
||
ids = request.POST.get("ids", "")
|
||
if not ids:
|
||
return JsonResponse({"error": "Нет ID для удаления"}, status=400)
|
||
|
||
try:
|
||
id_list = [int(x) for x in ids.split(",") if x.isdigit()]
|
||
deleted_count, _ = ObjItem.objects.filter(id__in=id_list).delete()
|
||
|
||
return JsonResponse(
|
||
{
|
||
"success": True,
|
||
"message": "Объект успешно удалён",
|
||
"deleted_count": deleted_count,
|
||
}
|
||
)
|
||
except Exception as e:
|
||
return JsonResponse({"error": f"Ошибка при удалении: {str(e)}"}, status=500)
|
||
|
||
|
||
class ObjItemListView(LoginRequiredMixin, View):
|
||
"""View for displaying a list of ObjItems with filtering and pagination."""
|
||
|
||
def get(self, request):
|
||
satellites = (
|
||
Satellite.objects.filter(parameters__objitem__isnull=False)
|
||
.distinct()
|
||
.only("id", "name")
|
||
.order_by("name")
|
||
)
|
||
|
||
selected_sat_id = request.GET.get("satellite_id")
|
||
page_number, items_per_page = parse_pagination_params(request)
|
||
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")
|
||
date_from = request.GET.get("date_from")
|
||
date_to = request.GET.get("date_to")
|
||
|
||
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",
|
||
"source",
|
||
"updated_by__user",
|
||
"created_by__user",
|
||
"lyngsat_source",
|
||
"parameter_obj",
|
||
"parameter_obj__id_satellite",
|
||
"parameter_obj__polarization",
|
||
"parameter_obj__modulation",
|
||
"parameter_obj__standard",
|
||
)
|
||
.prefetch_related(
|
||
"parameter_obj__sigma_parameter",
|
||
"parameter_obj__sigma_parameter__polarization",
|
||
)
|
||
.filter(parameter_obj__id_satellite_id__in=selected_satellites)
|
||
)
|
||
else:
|
||
objects = ObjItem.objects.select_related(
|
||
"geo_obj",
|
||
"source",
|
||
"updated_by__user",
|
||
"created_by__user",
|
||
"lyngsat_source",
|
||
"parameter_obj",
|
||
"parameter_obj__id_satellite",
|
||
"parameter_obj__polarization",
|
||
"parameter_obj__modulation",
|
||
"parameter_obj__standard",
|
||
).prefetch_related(
|
||
"parameter_obj__sigma_parameter",
|
||
"parameter_obj__sigma_parameter__polarization",
|
||
)
|
||
|
||
if freq_min is not None and freq_min.strip() != "":
|
||
try:
|
||
freq_min_val = float(freq_min)
|
||
objects = objects.filter(
|
||
parameter_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(
|
||
parameter_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(
|
||
parameter_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(
|
||
parameter_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(parameter_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(parameter_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(
|
||
parameter_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(
|
||
parameter_obj__bod_velocity__lte=bod_max_val
|
||
)
|
||
except ValueError:
|
||
pass
|
||
|
||
if selected_modulations:
|
||
objects = objects.filter(
|
||
parameter_obj__modulation__id__in=selected_modulations
|
||
)
|
||
|
||
if selected_polarizations:
|
||
objects = objects.filter(
|
||
parameter_obj__polarization__id__in=selected_polarizations
|
||
)
|
||
|
||
if has_kupsat == "1":
|
||
objects = objects.filter(source__coords_kupsat__isnull=False)
|
||
elif has_kupsat == "0":
|
||
objects = objects.filter(source__coords_kupsat__isnull=True)
|
||
|
||
if has_valid == "1":
|
||
objects = objects.filter(source__coords_valid__isnull=False)
|
||
elif has_valid == "0":
|
||
objects = objects.filter(source__coords_valid__isnull=True)
|
||
|
||
# Date filter for geo_obj timestamp
|
||
if date_from and date_from.strip():
|
||
try:
|
||
from datetime import datetime
|
||
date_from_obj = datetime.strptime(date_from, "%Y-%m-%d")
|
||
objects = objects.filter(geo_obj__timestamp__gte=date_from_obj)
|
||
except (ValueError, TypeError):
|
||
pass
|
||
|
||
if date_to and date_to.strip():
|
||
try:
|
||
from datetime import datetime, timedelta
|
||
date_to_obj = datetime.strptime(date_to, "%Y-%m-%d")
|
||
# Add one day to include the entire end date
|
||
date_to_obj = date_to_obj + timedelta(days=1)
|
||
objects = objects.filter(geo_obj__timestamp__lt=date_to_obj)
|
||
except (ValueError, TypeError):
|
||
pass
|
||
|
||
# Filter by source type (lyngsat_source)
|
||
has_source_type = request.GET.get("has_source_type")
|
||
if has_source_type == "1":
|
||
objects = objects.filter(lyngsat_source__isnull=False)
|
||
elif has_source_type == "0":
|
||
objects = objects.filter(lyngsat_source__isnull=True)
|
||
|
||
# Filter by sigma (sigma parameters)
|
||
has_sigma = request.GET.get("has_sigma")
|
||
if has_sigma == "1":
|
||
objects = objects.filter(parameter_obj__sigma_parameter__isnull=False)
|
||
elif has_sigma == "0":
|
||
objects = objects.filter(parameter_obj__sigma_parameter__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
|
||
|
||
objects = objects.annotate(
|
||
first_param_freq=F("parameter_obj__frequency"),
|
||
first_param_range=F("parameter_obj__freq_range"),
|
||
first_param_snr=F("parameter_obj__snr"),
|
||
first_param_bod=F("parameter_obj__bod_velocity"),
|
||
first_param_sat_name=F("parameter_obj__id_satellite__name"),
|
||
first_param_pol_name=F("parameter_obj__polarization__name"),
|
||
first_param_mod_name=F("parameter_obj__modulation__name"),
|
||
)
|
||
|
||
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 = getattr(obj, 'parameter_obj', None)
|
||
|
||
geo_coords = "-"
|
||
geo_timestamp = "-"
|
||
geo_location = "-"
|
||
kupsat_coords = "-"
|
||
valid_coords = "-"
|
||
distance_geo_kup = "-"
|
||
distance_geo_valid = "-"
|
||
distance_kup_valid = "-"
|
||
|
||
if hasattr(obj, "geo_obj") and obj.geo_obj:
|
||
geo_timestamp = obj.geo_obj.timestamp
|
||
geo_location = obj.geo_obj.location
|
||
|
||
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}"
|
||
|
||
satellite_name = "-"
|
||
frequency = "-"
|
||
freq_range = "-"
|
||
polarization_name = "-"
|
||
bod_velocity = "-"
|
||
modulation_name = "-"
|
||
snr = "-"
|
||
standard_name = "-"
|
||
comment = "-"
|
||
is_average = "-"
|
||
|
||
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 "-"
|
||
)
|
||
|
||
if hasattr(param, "standard") and param.standard:
|
||
standard_name = (
|
||
param.standard.name
|
||
if hasattr(param.standard, "name")
|
||
else "-"
|
||
)
|
||
|
||
if hasattr(obj, "geo_obj") and obj.geo_obj:
|
||
comment = obj.geo_obj.comment or "-"
|
||
is_average = "Да" if obj.geo_obj.is_average else "Нет" if obj.geo_obj.is_average is not None else "-"
|
||
|
||
source_type = "ТВ" if obj.lyngsat_source else "-"
|
||
|
||
has_sigma = False
|
||
sigma_info = "-"
|
||
if param:
|
||
sigma_count = param.sigma_parameter.count()
|
||
if sigma_count > 0:
|
||
has_sigma = True
|
||
first_sigma = param.sigma_parameter.first()
|
||
if first_sigma:
|
||
sigma_freq = f"{first_sigma.transfer_frequency:.3f}" if first_sigma.transfer_frequency else "-"
|
||
sigma_range = f"{first_sigma.freq_range:.3f}" if first_sigma.freq_range else "-"
|
||
sigma_pol = first_sigma.polarization.name if first_sigma.polarization else "-"
|
||
sigma_pol_short = sigma_pol[0] if sigma_pol and sigma_pol != "-" else "-"
|
||
sigma_info = f"{sigma_freq}/{sigma_range}/{sigma_pol_short}"
|
||
|
||
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_location": geo_location,
|
||
"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 "-",
|
||
"comment": comment,
|
||
"is_average": is_average,
|
||
"source_type": source_type,
|
||
"standard": standard_name,
|
||
"has_sigma": has_sigma,
|
||
"sigma_info": sigma_info,
|
||
"obj": obj,
|
||
}
|
||
)
|
||
|
||
modulations = Modulation.objects.all()
|
||
polarizations = Polarization.objects.all()
|
||
|
||
# Get the new filter values
|
||
has_source_type = request.GET.get("has_source_type")
|
||
has_sigma = request.GET.get("has_sigma")
|
||
|
||
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,
|
||
"date_from": date_from,
|
||
"date_to": date_to,
|
||
"has_source_type": has_source_type,
|
||
"has_sigma": has_sigma,
|
||
"modulations": modulations,
|
||
"polarizations": polarizations,
|
||
"full_width_page": True,
|
||
"sort": sort_param,
|
||
}
|
||
|
||
return render(request, "mainapp/objitem_list.html", context)
|
||
|
||
|
||
class ObjItemFormView(
|
||
RoleRequiredMixin, CoordinateProcessingMixin, FormMessageMixin, UpdateView
|
||
):
|
||
"""
|
||
Base class for creating and editing ObjItem.
|
||
|
||
Contains common logic for form processing, coordinates, and parameters.
|
||
"""
|
||
|
||
model = ObjItem
|
||
form_class = ObjItemForm
|
||
template_name = "mainapp/objitem_form.html"
|
||
success_url = reverse_lazy("mainapp:home")
|
||
required_roles = ["admin", "moderator"]
|
||
|
||
def get_success_url(self):
|
||
"""Returns URL with saved filter parameters."""
|
||
if self.request.GET:
|
||
from urllib.parse import urlencode
|
||
query_string = urlencode(self.request.GET)
|
||
return reverse_lazy("mainapp:objitem_list") + '?' + query_string
|
||
return reverse_lazy("mainapp:objitem_list")
|
||
|
||
def get_context_data(self, **kwargs):
|
||
context = super().get_context_data(**kwargs)
|
||
context["LEAFLET_CONFIG"] = {
|
||
"DEFAULT_CENTER": (55.75, 37.62),
|
||
"DEFAULT_ZOOM": 5,
|
||
}
|
||
|
||
# Save return parameters for "Back" button
|
||
context["return_params"] = self.request.GET.get('return_params', '')
|
||
|
||
# Work with single parameter form instead of formset
|
||
if self.object and hasattr(self.object, "parameter_obj") and self.object.parameter_obj:
|
||
context["parameter_form"] = ParameterForm(
|
||
instance=self.object.parameter_obj, prefix="parameter"
|
||
)
|
||
else:
|
||
context["parameter_form"] = ParameterForm(prefix="parameter")
|
||
|
||
if self.object and hasattr(self.object, "geo_obj") and self.object.geo_obj:
|
||
context["geo_form"] = GeoForm(
|
||
instance=self.object.geo_obj, prefix="geo"
|
||
)
|
||
else:
|
||
context["geo_form"] = GeoForm(prefix="geo")
|
||
|
||
return context
|
||
|
||
def form_valid(self, form):
|
||
# Get parameter form
|
||
if self.object and hasattr(self.object, "parameter_obj") and self.object.parameter_obj:
|
||
parameter_form = ParameterForm(
|
||
self.request.POST,
|
||
instance=self.object.parameter_obj,
|
||
prefix="parameter"
|
||
)
|
||
else:
|
||
parameter_form = ParameterForm(self.request.POST, prefix="parameter")
|
||
|
||
if self.object and hasattr(self.object, "geo_obj") and self.object.geo_obj:
|
||
geo_form = GeoForm(self.request.POST, instance=self.object.geo_obj, prefix="geo")
|
||
else:
|
||
geo_form = GeoForm(self.request.POST, prefix="geo")
|
||
|
||
# Save main object
|
||
self.object = form.save(commit=False)
|
||
self.set_user_fields()
|
||
self.object.save()
|
||
|
||
# Save related parameter
|
||
if parameter_form.is_valid():
|
||
self.save_parameter(parameter_form)
|
||
else:
|
||
context = self.get_context_data()
|
||
context.update({
|
||
'form': form,
|
||
'parameter_form': parameter_form,
|
||
'geo_form': geo_form,
|
||
})
|
||
return self.render_to_response(context)
|
||
|
||
# Save geo data
|
||
if geo_form.is_valid():
|
||
self.save_geo_data(geo_form)
|
||
else:
|
||
context = self.get_context_data()
|
||
context.update({
|
||
'form': form,
|
||
'parameter_form': parameter_form,
|
||
'geo_form': geo_form,
|
||
})
|
||
return self.render_to_response(context)
|
||
|
||
return super().form_valid(form)
|
||
|
||
def set_user_fields(self):
|
||
"""Sets user fields for the object."""
|
||
raise NotImplementedError("Subclasses must implement set_user_fields()")
|
||
|
||
def save_parameter(self, parameter_form):
|
||
"""Saves object parameter through OneToOne relationship."""
|
||
if parameter_form.is_valid():
|
||
instance = parameter_form.save(commit=False)
|
||
instance.objitem = self.object
|
||
instance.save()
|
||
|
||
def save_geo_data(self, geo_form):
|
||
"""Saves object geo data."""
|
||
geo_instance = self.get_or_create_geo_instance()
|
||
|
||
# Update fields from 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"]
|
||
|
||
# Process date/time
|
||
self.process_timestamp(geo_instance)
|
||
|
||
geo_instance.save()
|
||
|
||
def get_or_create_geo_instance(self):
|
||
"""Gets or creates Geo instance."""
|
||
if hasattr(self.object, "geo_obj") and self.object.geo_obj:
|
||
return self.object.geo_obj
|
||
return Geo(objitem=self.object)
|
||
|
||
|
||
class ObjItemUpdateView(ObjItemFormView):
|
||
"""View for editing ObjItem."""
|
||
|
||
success_message = "Объект успешно сохранён!"
|
||
|
||
def set_user_fields(self):
|
||
self.object.updated_by = self.request.user.customuser
|
||
|
||
|
||
class ObjItemCreateView(ObjItemFormView, CreateView):
|
||
"""View for creating ObjItem."""
|
||
|
||
success_message = "Объект успешно создан!"
|
||
|
||
def set_user_fields(self):
|
||
self.object.created_by = self.request.user.customuser
|
||
self.object.updated_by = self.request.user.customuser
|
||
|
||
|
||
class ObjItemDeleteView(RoleRequiredMixin, FormMessageMixin, DeleteView):
|
||
"""View for deleting ObjItem."""
|
||
|
||
model = ObjItem
|
||
template_name = "mainapp/objitem_confirm_delete.html"
|
||
success_url = reverse_lazy("mainapp:objitem_list")
|
||
success_message = "Объект успешно удалён!"
|
||
required_roles = ["admin", "moderator"]
|
||
|
||
def get_success_url(self):
|
||
"""Returns URL with saved filter parameters."""
|
||
if self.request.GET:
|
||
from urllib.parse import urlencode
|
||
query_string = urlencode(self.request.GET)
|
||
return reverse_lazy("mainapp:objitem_list") + '?' + query_string
|
||
return reverse_lazy("mainapp:objitem_list")
|
||
|
||
|
||
class ObjItemDetailView(LoginRequiredMixin, View):
|
||
"""
|
||
View for displaying ObjItem details in read-only mode.
|
||
|
||
Available to all authenticated users, displays data in read-only mode.
|
||
"""
|
||
def get(self, request, pk):
|
||
obj = ObjItem.objects.filter(pk=pk).select_related(
|
||
'geo_obj',
|
||
'updated_by__user',
|
||
'created_by__user',
|
||
'parameter_obj',
|
||
'parameter_obj__id_satellite',
|
||
'parameter_obj__polarization',
|
||
'parameter_obj__modulation',
|
||
'parameter_obj__standard',
|
||
).first()
|
||
|
||
if not obj:
|
||
from django.http import Http404
|
||
raise Http404("Объект не найден")
|
||
|
||
# Save return parameters for "Back" button
|
||
return_params = request.GET.get('return_params', '')
|
||
|
||
context = {
|
||
'object': obj,
|
||
'return_params': return_params
|
||
}
|
||
|
||
return render(request, "mainapp/objitem_detail.html", context)
|