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

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)