dev
AlexP077 3 years ago committed by Dmitry Titov
parent 2501fd3308
commit 00a47b3672

@ -27,6 +27,7 @@ services:
command: > command: >
sh -c "python manage.py migrate && sh -c "python manage.py migrate &&
python manage.py collectstatic --noinput && python manage.py collectstatic --noinput &&
python manage.py loaddata fixtures/groups.json
python manage.py runserver 0.0.0.0:${DJANGO_PORT}" python manage.py runserver 0.0.0.0:${DJANGO_PORT}"
environment: environment:
<<: *postgres-variables <<: *postgres-variables

@ -0,0 +1 @@
[{"model": "auth.group", "pk": 1, "fields": {"name": "Администратор пользователей", "permissions": [13, 14, 15, 16]}}, {"model": "auth.group", "pk": 2, "fields": {"name": "Зритель", "permissions": [28]}}, {"model": "auth.group", "pk": 3, "fields": {"name": "Редактор", "permissions": [25, 26, 27, 28]}}]

@ -61,8 +61,7 @@ ROOT_URLCONF = 'postamates.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'] 'DIRS': [BASE_DIR / 'templates'],
,
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -139,7 +138,9 @@ CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW = True CORS_ORIGIN_ALLOW = True
# DB_URL = 'postgresql://postamates_user:postamates_pass@postamates.spatiality.website:5481/postamates_db' # DB_URL = 'postgresql://postamates_user:postamates_pass@postamates.spatiality.website:5481/postamates_db'
DB_URL = f"postgresql://{os.getenv('POSTGRES_USER', 'postgres')}:{os.getenv('POSTGRES_PASSWORD', 'postgres')}@{os.getenv('POSTGRES_HOST', 'postgres')}:{os.getenv('POSTGRES_PORT', 'postgres')}/{os.getenv('POSTGRES_DB', 'postgres')}" DB_URL = f"postgresql://{os.getenv('POSTGRES_USER', 'postgres')}:" \
f"{os.getenv('POSTGRES_PASSWORD', 'postgres')}@{os.getenv('POSTGRES_HOST', 'postgres')}:" \
f"{os.getenv('POSTGRES_PORT', 'postgres')}/{os.getenv('POSTGRES_DB', 'postgres')}"
if os.getenv('local') is not None: if os.getenv('local') is not None:
GDAL_LIBRARY_PATH = '/opt/homebrew/opt/gdal/lib/libgdal.dylib' GDAL_LIBRARY_PATH = '/opt/homebrew/opt/gdal/lib/libgdal.dylib'
GEOS_LIBRARY_PATH = '/opt/homebrew/opt/geos/lib/libgeos_c.dylib' GEOS_LIBRARY_PATH = '/opt/homebrew/opt/geos/lib/libgeos_c.dylib'

@ -1,14 +1,13 @@
from django.contrib import admin from django.contrib import admin
from django.db import models
from django.urls import path
from service.models import PlacementPoint,AO,Rayon from service.models import PlacementPoint, AO, Rayon
from django.shortcuts import render
admin.site.register(AO) admin.site.register(AO)
admin.site.register(Rayon) admin.site.register(Rayon)
class PlacementPointAdmin(admin.ModelAdmin): class PlacementPointAdmin(admin.ModelAdmin):
pass pass
admin.site.register(PlacementPoint,PlacementPointAdmin)
admin.site.register(PlacementPoint, PlacementPointAdmin)

@ -0,0 +1,19 @@
# Generated by Django 3.2 on 2023-03-08 11:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('service', '0007_placementpoint_location_id'),
]
operations = [
migrations.AlterField(
model_name='rayon',
name='AO',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rayons', to='service.ao'),
),
]

@ -1,6 +1,6 @@
from django.contrib.gis.db import models as gis_models from django.contrib.gis.db import models as gis_models
from django.db import models from django.db import models
from service.signals import *
class PlacementPoint(models.Model): class PlacementPoint(models.Model):
location_id = models.IntegerField(null=False, blank=False,unique=True) location_id = models.IntegerField(null=False, blank=False,unique=True)

@ -0,0 +1,11 @@
from rest_framework import permissions
class UserPermission(permissions.BasePermission):
def has_permission(self, request, view):
if view.action in ['update_fact', 'update_status', 'retrieve',
'update', 'partial_update', 'destroy', 'create']:
return request.user.groups.filter(name='Редактор').exists()
else:
return request.user.groups.filter(
name__in=('Зритель', 'Редактор')).exists()

@ -1,4 +1,5 @@
from rest_framework import serializers from rest_framework import serializers
from service import models from service import models
@ -6,14 +7,17 @@ class PlacementPointSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.PlacementPoint model = models.PlacementPoint
fields = '__all__' fields = '__all__'
class RayonSerializer(serializers.ModelSerializer): class RayonSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.AO model = models.AO
fields = '__all__' fields = '__all__'
class AOSerializer(serializers.ModelSerializer): class AOSerializer(serializers.ModelSerializer):
rayons = RayonSerializer(many=True, read_only=True) rayons = RayonSerializer(many=True, read_only=True)
class Meta: class Meta:
model = models.AO model = models.AO
fields = '__all__' fields = '__all__'

@ -0,0 +1,11 @@
from django.contrib.auth.models import Group
from rest_registration.signals import user_registered
def user_created(sender, user, request, **kwargs):
group = Group.objects.get(name='Зритель')
group.user_set.add(user)
user.save()
user_registered.connect(user_created)

@ -31,6 +31,7 @@ urlpatterns = [
path('ao_rayons', views.AOViewSet.as_view({'get': 'list'}), name='ao_and_rayons'), path('ao_rayons', views.AOViewSet.as_view({'get': 'list'}), name='ao_and_rayons'),
url(r'load_csv/', views.refresh_placement_points.as_view(), name='upload_placement_points'), 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'), url(r'upload_ao_and_rayons/', views.load_ao_and_rayons.as_view(), name='upload_ao_and_rayons'),
url(r'me/', views.get_current_user, name='me'),
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), re_path(r'^swagger(?P<format>\.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'^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'), # re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),

@ -3,33 +3,32 @@ from io import BytesIO
import pandas as pd import pandas as pd
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse from django.http import HttpResponse, JsonResponse
from rest_framework import status from rest_framework import status
from rest_framework import status as http_status from rest_framework import status as http_status
from rest_framework.decorators import action from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.viewsets import ReadOnlyModelViewSet
from service import serializers, models, pagination from service import serializers, models, pagination
from service import utils from service import utils
from service.permissions import UserPermission
from service.utils import load_data from service.utils import load_data
class RayonViewSet(ReadOnlyModelViewSet):
serializer_class = serializers.RayonSerializer
queryset = models.Rayon.objects
class AOViewSet(ReadOnlyModelViewSet): class AOViewSet(ReadOnlyModelViewSet):
serializer_class = serializers.AOSerializer serializer_class = serializers.AOSerializer
queryset = models.AO.objects queryset = models.AO.objects
permission_classes = [UserPermission]
class PlacementPointViewSet(ReadOnlyModelViewSet): class PlacementPointViewSet(ReadOnlyModelViewSet):
serializer_class = serializers.PlacementPointSerializer serializer_class = serializers.PlacementPointSerializer
queryset = models.PlacementPoint.objects queryset = models.PlacementPoint.objects
pagination_class = pagination.MyPagination pagination_class = pagination.MyPagination
permission_classes = [UserPermission]
def get_queryset(self): def get_queryset(self):
qs = self.queryset.all() qs = self.queryset.all()
@ -88,55 +87,111 @@ class PlacementPointViewSet(ReadOnlyModelViewSet):
qs = qs.filter(~Q(location_id__in=excluded)) qs = qs.filter(~Q(location_id__in=excluded))
if included: if included:
inclded = list(included.split(',')) inclded = list(included.split(','))
qs2 = models.PlacementPoint.objects.filter(location_id__in=inclded).all() qs2 = models.PlacementPoint.objects.filter(
location_id__in=inclded).all()
qs = (qs | qs2).distinct() qs = (qs | qs2).distinct()
return qs return qs
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def filters(self, request): def filters(self, request):
qs = self.get_queryset() qs = self.get_queryset()
age_day = [x for x in list(set(qs.values_list('age_day', flat=True))) if x is not None] age_day = [x for x in list(set(qs.values_list('age_day', flat=True)))
prediction_first = [x for x in list(set(qs.values_list('prediction_first', flat=True))) if x is not None] if
prediction_current = [x for x in list(set(qs.values_list('prediction_current', flat=True))) if x is not None] x is not None]
plan_first = [x for x in list(set(qs.values_list('plan_first', flat=True))) if x is not None] prediction_first = [x for x in list(
plan_current = [x for x in list(set(qs.values_list('plan_current', flat=True))) if x is not None] set(qs.values_list('prediction_first', flat=True))) if
fact = [x for x in list(set(qs.values_list('fact', flat=True))) if x is not None] x is not None]
delta_first = [x for x in list(set(qs.values_list('delta_first', flat=True))) if x is not None] prediction_current = [x for x in list(
delta_current = [x for x in list(set(qs.values_list('delta_current', flat=True))) if x is not None] set(qs.values_list('prediction_current', flat=True))) if
flat_cnt = [x for x in list(set(qs.values_list('flat_cnt', flat=True))) if x is not None] x is not None]
year_bld = [x for x in list(set(qs.values_list('year_bld', flat=True))) if x is not None] plan_first = [x for x in
levels = [x for x in list(set(qs.values_list('levels', flat=True))) if x is not None] list(set(qs.values_list('plan_first', flat=True))) if
doors = [x for x in list(set(qs.values_list('doors', flat=True))) if x is not None] x is not None]
flats_cnt = [x for x in list(set(qs.values_list('flats_cnt', flat=True))) if x is not None] plan_current = [x for x in
popul_home = [x for x in list(set(qs.values_list('popul_home', flat=True))) if x is not None] list(set(qs.values_list('plan_current', flat=True))) if
popul_job = [x for x in list(set(qs.values_list('popul_job', flat=True))) if x is not None] x is not None]
other_post_cnt = [x for x in list(set(qs.values_list('other_post_cnt', flat=True))) if x is not None] fact = [x for x in list(set(qs.values_list('fact', flat=True))) if
target_post_cnt = [x for x in list(set(qs.values_list('target_post_cnt', flat=True))) if x is not None] x is not None]
yndxfood_cnt = [x for x in list(set(qs.values_list('yndxfood_cnt', flat=True))) if x is not None] delta_first = [x for x in
yndxfood_sum = [x for x in list(set(qs.values_list('yndxfood_sum', flat=True))) if x is not None] list(set(qs.values_list('delta_first', flat=True))) if
yndxfood_cnt_cst = [x for x in list(set(qs.values_list('yndxfood_cnt_cst', flat=True))) if x is not None] x is not None]
delta_current = [x for x in
list(set(qs.values_list('delta_current', flat=True)))
if x is not None]
flat_cnt = [x for x in list(set(qs.values_list('flat_cnt', flat=True)))
if x is not None]
year_bld = [x for x in list(set(qs.values_list('year_bld', flat=True)))
if x is not None]
levels = [x for x in list(set(qs.values_list('levels', flat=True))) if
x is not None]
doors = [x for x in list(set(qs.values_list('doors', flat=True))) if
x is not None]
flats_cnt = [x for x in
list(set(qs.values_list('flats_cnt', flat=True))) if
x is not None]
popul_home = [x for x in
list(set(qs.values_list('popul_home', flat=True))) if
x is not None]
popul_job = [x for x in
list(set(qs.values_list('popul_job', flat=True))) if
x is not None]
other_post_cnt = [x for x in
list(
set(qs.values_list('other_post_cnt', flat=True)))
if x is not None]
target_post_cnt = [x for x in list(
set(qs.values_list('target_post_cnt', flat=True))) if
x is not None]
yndxfood_cnt = [x for x in
list(set(qs.values_list('yndxfood_cnt', flat=True))) if
x is not None]
yndxfood_sum = [x for x in
list(set(qs.values_list('yndxfood_sum', flat=True))) if
x is not None]
yndxfood_cnt_cst = [x for x in list(
set(qs.values_list('yndxfood_cnt_cst', flat=True))) if
x is not None]
data = { data = {
"age_day": [min(age_day), max(age_day)] if age_day else [0, 2030], "age_day": [min(age_day), max(age_day)] if age_day else [0, 2030],
"prediction_first": [min(prediction_first), max(prediction_first)] if prediction_first else [-22, 22], "prediction_first": [min(prediction_first), max(
"prediction_current": [min(prediction_current), max(prediction_current)] if prediction_current else [-22, prediction_first)] if prediction_first else [-22, 22],
"prediction_current": [min(prediction_current), max(
prediction_current)] if prediction_current else [-22,
22], 22],
"plan_first": [min(plan_first), max(plan_first)] if plan_first else [0, 100], "plan_first": [min(plan_first),
"plan_current": [min(plan_current), max(plan_current)] if plan_current else [0, 100], max(plan_first)] if plan_first else [0, 100],
"plan_current": [min(plan_current),
max(plan_current)] if plan_current else [0, 100],
"fact": [min(fact), max(fact)] if fact else [0, 100], "fact": [min(fact), max(fact)] if fact else [0, 100],
"delta_first": [min(delta_first), max(delta_first)] if delta_first else [0, 100], "delta_first": [min(delta_first),
"delta_current": [min(delta_current), max(delta_current)] if delta_current else [0, 100], max(delta_first)] if delta_first else [0, 100],
"flat_cnt": [min(flat_cnt), max(flat_cnt)] if flat_cnt else [0, 100], "delta_current": [min(delta_current),
"year_bld": [min(year_bld), max(year_bld)] if year_bld else [0, 2030], max(delta_current)] if delta_current else [0,
100],
"flat_cnt": [min(flat_cnt), max(flat_cnt)] if flat_cnt else [0,
100],
"year_bld": [min(year_bld), max(year_bld)] if year_bld else [0,
2030],
"levels": [min(levels), max(levels)] if levels else [0, 100], "levels": [min(levels), max(levels)] if levels else [0, 100],
"doors ": [min(doors), max(doors)] if doors else [0, 100], "doors ": [min(doors), max(doors)] if doors else [0, 100],
"flats_cnt": [min(flats_cnt), max(flats_cnt)] if flats_cnt else [0, 100], "flats_cnt": [min(flats_cnt), max(flats_cnt)] if flats_cnt else [0,
"popul_home": [min(popul_home), max(popul_home)] if popul_home else [0, 100], 100],
"popul_job": [min(popul_job), max(popul_job)] if popul_job else [0, 100], "popul_home": [min(popul_home),
"other_post_cnt": [min(other_post_cnt), max(other_post_cnt)] if other_post_cnt else [0, 100], max(popul_home)] if popul_home else [0, 100],
"target_post_cnt": [min(target_post_cnt), max(target_post_cnt)] if target_post_cnt else [0, 100], "popul_job": [min(popul_job), max(popul_job)] if popul_job else [0,
"yndxfood_cnt": [min(yndxfood_cnt), max(yndxfood_cnt)] if yndxfood_cnt else [0, 100], 100],
"yndxfood_sum": [min(yndxfood_sum), max(yndxfood_sum)] if yndxfood_sum else [0, 100], "other_post_cnt": [min(other_post_cnt),
"yndxfood_cnt_cst": [min(yndxfood_cnt_cst), max(yndxfood_cnt_cst)] if yndxfood_cnt_cst else [0, 100], max(other_post_cnt)] if other_post_cnt else [0,
100],
"target_post_cnt": [min(target_post_cnt),
max(target_post_cnt)] if target_post_cnt else [
0, 100],
"yndxfood_cnt": [min(yndxfood_cnt),
max(yndxfood_cnt)] if yndxfood_cnt else [0, 100],
"yndxfood_sum": [min(yndxfood_sum),
max(yndxfood_sum)] if yndxfood_sum else [0, 100],
"yndxfood_cnt_cst": [min(yndxfood_cnt_cst), max(
yndxfood_cnt_cst)] if yndxfood_cnt_cst else [0, 100],
} }
return Response(data, status=status.HTTP_200_OK) return Response(data, status=status.HTTP_200_OK)
@ -161,7 +216,8 @@ class PlacementPointViewSet(ReadOnlyModelViewSet):
if not new_status: if not new_status:
return Response({'message': 'No status'}, 400) return Response({'message': 'No status'}, 400)
qs.update(**{'status': new_status}) qs.update(**{'status': new_status})
return Response({'message': 'status updated'}, status=http_status.HTTP_200_OK) return Response({'message': 'status updated'},
status=http_status.HTTP_200_OK)
@action(detail=False, methods=['put']) @action(detail=False, methods=['put'])
def update_fact(self, request): def update_fact(self, request):
@ -173,7 +229,8 @@ class PlacementPointViewSet(ReadOnlyModelViewSet):
if not qs: if not qs:
return Response(status=http_status.HTTP_404_NOT_FOUND) return Response(status=http_status.HTTP_404_NOT_FOUND)
qs.update(**{'fact': fact}) qs.update(**{'fact': fact})
return Response({'message': 'fact updated'}, status=http_status.HTTP_200_OK) return Response({'message': 'fact updated'},
status=http_status.HTTP_200_OK)
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def to_excel(self, request): def to_excel(self, request):
@ -183,7 +240,8 @@ class PlacementPointViewSet(ReadOnlyModelViewSet):
data['sample_trn'] = data['sample_trn'].astype(int) data['sample_trn'] = data['sample_trn'].astype(int)
with BytesIO() as b: with BytesIO() as b:
with pd.ExcelWriter(b) as writer: with pd.ExcelWriter(b) as writer:
data.to_excel(writer, sheet_name="Placement Points", index=False) data.to_excel(writer, sheet_name="Placement Points",
index=False)
filename = "placement_points.xlsx" filename = "placement_points.xlsx"
res = HttpResponse( res = HttpResponse(
@ -196,7 +254,10 @@ class PlacementPointViewSet(ReadOnlyModelViewSet):
@action(detail=False, methods=['get']) @action(detail=False, methods=['get'])
def get_10k(self, request): def get_10k(self, request):
if models.PlacementPoint.objects.count() > 10000: if models.PlacementPoint.objects.count() > 10000:
qs = models.PlacementPoint.objects.order_by('-prediction_current').all()[10000] qs = \
models.PlacementPoint.objects.order_by(
'-prediction_current').all()[
10000]
return Response({'prediction_current': qs.prediction_current}, 200) return Response({'prediction_current': qs.prediction_current}, 200)
return Response( return Response(
{'prediction_current': models.PlacementPoint.objects.order_by( {'prediction_current': models.PlacementPoint.objects.order_by(
@ -221,3 +282,10 @@ class load_ao_and_rayons(APIView):
file_rayon = request.FILES['file_rayon'] file_rayon = request.FILES['file_rayon']
utils.load_ao_and_rayons(file_ao, file_rayon) utils.load_ao_and_rayons(file_ao, file_rayon)
return Response(status=http_status.HTTP_200_OK) return Response(status=http_status.HTTP_200_OK)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_current_user(request):
return JsonResponse(
{'groups': [gr.name for gr in request.user.groups.all()]})

Loading…
Cancel
Save