You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
5.1 KiB
131 lines
5.1 KiB
import datetime
|
|
from service import serializers
|
|
from service import models
|
|
from rest_framework import viewsets
|
|
from rest_framework.permissions import AllowAny
|
|
from django.core.serializers import serialize
|
|
from rest_framework.response import Response
|
|
import json
|
|
from django.core.cache import cache
|
|
from rest_framework import status
|
|
from rest_framework.decorators import action
|
|
from django.db.models import Max, Min
|
|
from django.conf import settings
|
|
from service.management.commands.create_poly import import_poly
|
|
from service.management.commands.create_points import import_points
|
|
from rest_framework.parsers import MultiPartParser
|
|
import os
|
|
from django.core.files.storage import default_storage
|
|
from django.core.files.base import ContentFile
|
|
from service.utils import get_model_column_names
|
|
from django.http import HttpResponseRedirect
|
|
from django.contrib import messages
|
|
|
|
|
|
def get_min_max_filters(model, exclude_fields_names):
|
|
d = {}
|
|
l = []
|
|
fields = get_model_column_names(model, exclude_fields_names)
|
|
for i in fields:
|
|
l.append(Min(i))
|
|
l.append(Max(i))
|
|
qs = model.objects.aggregate(*l)
|
|
for i in fields:
|
|
d[i] = [qs[f'{i}__min'], qs[f'{i}__max']]
|
|
return d
|
|
|
|
|
|
def get_full_filters(model, exclude_fields_names):
|
|
d = {}
|
|
fields = get_model_column_names(model, exclude_fields_names)
|
|
values = model.objects.defer('pk').values(*fields)
|
|
for n, i in enumerate(fields):
|
|
d[i] = sorted([v[i] for v in values])
|
|
return d
|
|
|
|
|
|
def get_model_naming(model):
|
|
return models.Config.objects.get(name=f'{model.__name__}').data
|
|
|
|
|
|
class PolygonViewSet(viewsets.ReadOnlyModelViewSet):
|
|
serializer_class = serializers.PolygonSerializer
|
|
permission_classes = [AllowAny]
|
|
parser_classes = (MultiPartParser,)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def filters(self, request):
|
|
d = cache.get('polygon_filters')
|
|
if settings.DEBUG:
|
|
d = None
|
|
if d is None:
|
|
d = get_full_filters(models.Polygon, ['id', 'geometry'])
|
|
cache.set('polygon_filters', d, 60 * 60 * 24)
|
|
return Response(d, status=status.HTTP_200_OK)
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def naming(self, request):
|
|
return Response(get_model_naming(models.Polygon), status=status.HTTP_200_OK)
|
|
|
|
@action(detail=False, methods=['post'])
|
|
def file_import(self, request):
|
|
try:
|
|
file = request.FILES['file'].file
|
|
path = default_storage.save(f'cells/cells_{datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.zip', ContentFile(file.read()))
|
|
import_poly(os.path.join(settings.MEDIA_ROOT, path))
|
|
cache.delete('polygon_filters')
|
|
messages.add_message(request, messages.INFO, 'Данные успешно импортированы')
|
|
except Exception as e:
|
|
messages.add_message(request, messages.ERROR, f'Ошибка импорта: {e}')
|
|
return HttpResponseRedirect('/admin/')
|
|
|
|
|
|
class PointViewSet(viewsets.ReadOnlyModelViewSet):
|
|
serializer_class = serializers.PointSerializer
|
|
permission_classes = [AllowAny]
|
|
queryset = models.Point.objects.all()
|
|
|
|
def list(self, request, *args, **kwargs):
|
|
queryset = self.get_queryset()
|
|
d = cache.get('points')
|
|
if settings.DEBUG:
|
|
d = None
|
|
if d is None:
|
|
d = json.loads(serialize('geojson', queryset,
|
|
geometry_field='point',
|
|
fields=get_model_column_names(models.Point,['point'])
|
|
))
|
|
cache.set('points', d, 60 * 60 * 24)
|
|
|
|
resp = Response(d)
|
|
resp["Access-Control-Allow-Origin"] = '*'
|
|
resp["Access-Control-Allow-Methods"] = 'GET,PUT, OPTIONS'
|
|
resp["Access-Control-Max-Age"] = '1000'
|
|
resp["Access-Control-Allow-Headers"] = 'X-Requested-With, Content-Type'
|
|
return resp
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def filters(self, request):
|
|
resp = Response(get_min_max_filters(models.Point, ['id', 'point', 'is2025']))
|
|
resp["Access-Control-Allow-Origin"] = '*'
|
|
resp["Access-Control-Allow-Methods"] = 'GET,PUT, OPTIONS'
|
|
resp["Access-Control-Max-Age"] = '1000'
|
|
resp["Access-Control-Allow-Headers"] = 'X-Requested-With, Content-Type'
|
|
return resp
|
|
|
|
@action(detail=False, methods=['post'])
|
|
def file_import(self, request):
|
|
try:
|
|
file = request.FILES['file'].file
|
|
path = default_storage.save(f'points/points_{datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}.csv', ContentFile(file.read()))
|
|
import_points(os.path.join(settings.MEDIA_ROOT, path))
|
|
cache.delete('points')
|
|
messages.add_message(request, messages.INFO, 'Данные успешно импортированы')
|
|
except Exception as e:
|
|
messages.add_message(request, messages.ERROR, f'Ошибка импорта: {e}')
|
|
return HttpResponseRedirect('/admin/')
|
|
|
|
@action(detail=False, methods=['get'])
|
|
def naming(self, request):
|
|
return Response(get_model_naming(models.Point), status=status.HTTP_200_OK)
|