diff --git a/service/admin.py b/service/admin.py index 7f83de9..426f064 100644 --- a/service/admin.py +++ b/service/admin.py @@ -1,6 +1,14 @@ from django.contrib import admin from django.db import models +from django.urls import path + from service.models import PlacementPoint,AO,Rayon -admin.site.register(PlacementPoint) +from django.shortcuts import render + admin.site.register(AO) -admin.site.register(Rayon) \ No newline at end of file +admin.site.register(Rayon) + +class PlacementPointAdmin(admin.ModelAdmin): + pass + +admin.site.register(PlacementPoint,PlacementPointAdmin) \ No newline at end of file diff --git a/service/migrations/0007_placementpoint_location_id.py b/service/migrations/0007_placementpoint_location_id.py new file mode 100644 index 0000000..b3d1cdd --- /dev/null +++ b/service/migrations/0007_placementpoint_location_id.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2 on 2023-02-24 10:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('service', '0006_alter_placementpoint_mat_nes'), + ] + + operations = [ + migrations.AddField( + model_name='placementpoint', + name='location_id', + field=models.IntegerField(default=None, unique=True), + preserve_default=False, + ), + ] diff --git a/service/models.py b/service/models.py index ea8a1c3..0793d4c 100644 --- a/service/models.py +++ b/service/models.py @@ -3,6 +3,7 @@ from django.db import models class PlacementPoint(models.Model): + location_id = models.IntegerField(null=False, blank=False,unique=True) address = models.TextField(null=True, blank=True, verbose_name='Адрес') name = models.TextField(null=True, blank=True, verbose_name='Название') category = models.TextField(null=True, blank=True, verbose_name='Категория') diff --git a/service/urls.py b/service/urls.py index 036ce69..9beb94b 100644 --- a/service/urls.py +++ b/service/urls.py @@ -1,9 +1,10 @@ +from django.conf.urls import url from django.urls import path, re_path, include -from service import views - -from rest_framework import permissions, routers -from drf_yasg.views import get_schema_view from drf_yasg import openapi +from drf_yasg.views import get_schema_view +from rest_framework import permissions, routers + +from service import views router = routers.DefaultRouter() router.register('', views.PlacementPointViewSet) @@ -26,6 +27,8 @@ urlpatterns = [ path('placement_points', include(router.urls), name='placement_points'), path('ao_and_rayons/', views.ao_and_rayons.as_view(), name='ao_and_rayons'), path('raschet/', views.raschet.as_view(), name='ao_and_rayons'), + url(r'load_csv/', views.refresh_placement_points.as_view(), name='upload_placement_points'), + url(r'upload_ao_and_rayons/', views.load_ao_and_rayons.as_view(), name='upload_ao_and_rayons'), re_path(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), # re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), diff --git a/service/utils.py b/service/utils.py index 0857b96..e9b3fd7 100644 --- a/service/utils.py +++ b/service/utils.py @@ -1,11 +1,12 @@ import geojson +import numpy as np import pandas as pd import sqlalchemy from django.conf import settings from django.contrib.gis.geos import GEOSGeometry from geojson import MultiPolygon from tqdm import tqdm -import numpy as np + from service import models @@ -67,33 +68,33 @@ def raschet(tables, filters, koefs, method): def load_data(filepath: str): models.PlacementPoint.objects.all().delete() - df = pd.read_csv(filepath).iloc[:, 1:] + df = pd.read_csv(filepath) df = df.replace(np.nan, None) df = df.replace('NaT', None) for row in tqdm(df.to_dict('records'), desc='Loading data...'): - data = {k: row[k] for k in row.keys() if k not in ['okrug','rayon','age_month']} - data['okrug']=models.AO.objects.get(name=row['okrug']) + data = {k: row[k] for k in row.keys() if k not in ['id', 'okrug', 'rayon', 'age_month']} + data['location_id'] = row['id'] + data['okrug'] = models.AO.objects.get(name=row['okrug']) data['rayon'] = models.Rayon.objects.get(name=row['rayon']) models.PlacementPoint.objects.create(**data) -def load_ao_and_rayons(ao_filepath: str='./fixtures/okrug.geojson', rayons_filepath: str = './fixtures/rayon.geojson'): +def load_ao_and_rayons(ao_filepath: str, + rayons_filepath: str): models.AO.objects.all().delete() models.Rayon.objects.all().delete() - with open(ao_filepath) as f: - gj = geojson.load(f) + gj = geojson.load(ao_filepath) objs = gj['features'] - for obj in objs: + for obj in tqdm(objs, desc='Loading AOs...'): name = obj['properties']['okrug'] coords = obj['geometry']['coordinates'] models.AO.objects.create(**{'name': name, 'polygon': GEOSGeometry(str(MultiPolygon(coords)))}) - with open(rayons_filepath) as f: - gj = geojson.load(f) + gj = geojson.load(rayons_filepath) objs = gj['features'] - for obj in objs: + for obj in tqdm(objs, desc='Loading Rayons...'): name = obj['properties']['rayon'] coords = obj['geometry']['coordinates'] okr = obj['properties']['okrug'] ao = models.AO.objects.get(name=okr) models.Rayon.objects.create(**{'name': name, 'polygon': GEOSGeometry(str(MultiPolygon(coords))), 'AO': ao}) - print('AO and Rayons loaded') \ No newline at end of file + print('AO and Rayons loaded') diff --git a/service/views.py b/service/views.py index 0d6f186..44374c2 100644 --- a/service/views.py +++ b/service/views.py @@ -8,10 +8,12 @@ from django.http import HttpResponse from rest_framework import permissions from rest_framework.generics import GenericAPIView from rest_framework.response import Response +from rest_framework.views import APIView from rest_framework.viewsets import ReadOnlyModelViewSet from service import serializers, models, pagination -from service.utils import raschet as raschet_alg +from service.utils import raschet as raschet_alg, load_data +from service import utils def rename_result_dataset(dataframe, rename_dict, reverse=False): @@ -214,9 +216,30 @@ class PlacementPointViewSet(ReadOnlyModelViewSet): qs = qs.filter(age__range=age) if excluded: excluded = list(excluded.split(',')) - qs = qs.filter(~Q(id__in=excluded)) + qs = qs.filter(~Q(location_id__in=excluded)) if included: inclded = list(included.split(',')) - qs2 = models.PlacementPoint.objects.filter(id__in=inclded).all() + qs2 = models.PlacementPoint.objects.filter(location_id__in=inclded).all() qs = (qs | qs2).distinct() return qs + + +import warnings + + +class refresh_placement_points(APIView): + @staticmethod + def post(request): + warnings.filterwarnings('ignore') + file = request.FILES['file'] + load_data(file) + return Response(200) + +class load_ao_and_rayons(APIView): + @staticmethod + def post(request): + warnings.filterwarnings('ignore') + file_ao = request.FILES['file_ao'] + file_rayon = request.FILES['file_rayon'] + utils.load_ao_and_rayons(file_ao,file_rayon) + return Response(200) \ No newline at end of file diff --git a/templates/admin/index.html b/templates/admin/index.html index b4b574d..bb18c24 100644 --- a/templates/admin/index.html +++ b/templates/admin/index.html @@ -51,9 +51,18 @@

Обновить файл точек

-
+ {% csrf_token %} - + + +
+

Загрузить районы и АО

+
+ {% csrf_token %} +

Файл с АО

+ +

Файл с Районами

+

Обновить файл полигонов