diff --git a/deploy/dockerfiles/Dockerfile b/deploy/dockerfiles/Dockerfile index 95d5f00..01aa35a 100644 --- a/deploy/dockerfiles/Dockerfile +++ b/deploy/dockerfiles/Dockerfile @@ -2,7 +2,8 @@ ARG YC_CONTAINER_REGISTRY FROM ${YC_CONTAINER_REGISTRY}/public/python:3.8 RUN apt-get update && \ - apt-get install -y binutils libproj-dev gdal-bin + apt-get install -y binutils libproj-dev gdal-bin && \ + apt-get install -y postgresql-client ENV PYTHONUNBUFFERED 1 diff --git a/fixtures/post_and_pvz.json b/fixtures/post_and_pvz.json index f5dc538..dcf2876 100644 --- a/fixtures/post_and_pvz.json +++ b/fixtures/post_and_pvz.json @@ -6,7 +6,7 @@ "name": "ПВЗ", "image": "", "visible": true, - "inlude_in_ml": true + "include_in_ml": true } }, { @@ -16,7 +16,7 @@ "name": "Постамат", "image": "", "visible": true, - "inlude_in_ml": true + "include_in_ml": true } } ] diff --git a/service/admin.py b/service/admin.py index df7db4b..9465df2 100644 --- a/service/admin.py +++ b/service/admin.py @@ -1,3 +1,5 @@ +import os + from django.contrib import admin from django.contrib.admin import AdminSite from django.contrib.admin.sites import NotRegistered @@ -12,7 +14,7 @@ from service.models import Post_and_pvz, Post_and_pvzCategory, Post_and_pvzGroup from service.models import PlacementPointPVZDistance, TaskStatus from postamates.settings import DEBUG from django.core.cache import cache -from service.layer_service import LayerService +from service.utils import run_psql_command class MyAdminSite(AdminSite): @@ -32,7 +34,7 @@ if DEBUG: class Post_and_PVZAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): - LayerService().count_post_pvz_for_placementpoint(obj) + obj.save() my_admin_site.register(Post_and_pvz, Post_and_PVZAdmin) @@ -55,6 +57,14 @@ class CategoryAdmin(admin.ModelAdmin): cache.clear() +class PostPvzCategoryAdmin(CategoryAdmin): + def delete_model(self, request, obj): + if obj.id in (1, 2): + pass + else: + super().delete_model(request, obj) + + class GroupAdmin(admin.ModelAdmin): list_display = ('name', 'category', 'visible') @@ -67,14 +77,20 @@ class GroupAdmin(admin.ModelAdmin): cache.clear() +class PostPvzGroupAdmin(GroupAdmin): + def save_model(self, request, obj, form, change): + run_psql_command() + super().save_model(request, obj, form, change) + + class PlacementPointAdmin(admin.ModelAdmin): pass my_admin_site.register(TaskStatus, TaskStatusAdmin) -my_admin_site.register(Post_and_pvzGroup, GroupAdmin) +my_admin_site.register(Post_and_pvzGroup, PostPvzGroupAdmin) my_admin_site.register(OtherObjectsGroup, GroupAdmin) -my_admin_site.register(Post_and_pvzCategory, CategoryAdmin) +my_admin_site.register(Post_and_pvzCategory, PostPvzCategoryAdmin) my_admin_site.register(OtherObjectsCategory, CategoryAdmin) my_admin_site.register(PlacementPoint, PlacementPointAdmin) diff --git a/service/apps.py b/service/apps.py index 8d0ae67..1a6fe55 100644 --- a/service/apps.py +++ b/service/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class ServiceConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'service' + + def ready(self): + from service import signals diff --git a/service/layer_service.py b/service/layer_service.py index 690d32a..bafda6d 100644 --- a/service/layer_service.py +++ b/service/layer_service.py @@ -17,9 +17,9 @@ class LayerService: @staticmethod def count_post_pvz(point): point.rivals_post_cnt = models.Post_and_pvz.objects.filter( - category__name="Постамат", inlude_in_ml=True, + category__name="Постамат", include_in_ml=True, wkt__distance_lt=(point.geometry, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).count() point.rivals_pvz_cnt = models.Post_and_pvz.objects.filter( - category__name="ПВЗ", inlude_in_ml=True, + category__name="ПВЗ", include_in_ml=True, wkt__distance_lt=(point.geometry, Distance(m=DEFAULT_PLACEMENT_POINT_UPDATE_RADIUS))).count() point.save() diff --git a/service/migrations/0026_auto_20230823_2016.py b/service/migrations/0026_auto_20230823_2016.py new file mode 100644 index 0000000..0d2205b --- /dev/null +++ b/service/migrations/0026_auto_20230823_2016.py @@ -0,0 +1,31 @@ +# Generated by Django 3.2 on 2023-08-23 17:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('service', '0025_auto_20230804_1349'), + ] + + operations = [ + migrations.RenameField( + model_name='post_and_pvz', + old_name='inlude_in_ml', + new_name='include_in_ml', + ), + migrations.RenameField( + model_name='post_and_pvzcategory', + old_name='inlude_in_ml', + new_name='include_in_ml', + ), + migrations.RenameField( + model_name='post_and_pvzgroup', + old_name='inlude_in_ml', + new_name='include_in_ml', + ), + migrations.DeleteModel( + name='PointDist', + ), + ] diff --git a/service/models.py b/service/models.py index 6b4b70b..4bfb7dc 100644 --- a/service/models.py +++ b/service/models.py @@ -3,6 +3,7 @@ from django.contrib.gis.db import models as gis_models from django.db import models from postamates.settings import SRID from service.enums import PointStatus +from service.layer_service import LayerService User._meta.get_field('email')._unique = True @@ -113,7 +114,7 @@ class Post_and_pvz(models.Model): on_delete=models.CASCADE) group = models.ForeignKey('Post_and_pvzGroup', default=None, related_name='post_and_pvz', on_delete=models.CASCADE) visible = models.BooleanField(default=True) - inlude_in_ml = models.BooleanField(default=True) + include_in_ml = models.BooleanField(default=True) class OtherObjects(models.Model): @@ -142,7 +143,7 @@ class Post_and_pvzCategory(models.Model): image = models.ImageField(blank=True, null=True, default=None, upload_to='post_and_pvz_category_images/', verbose_name='Картинка') visible = models.BooleanField(default=True) - inlude_in_ml = models.BooleanField(default=True) + include_in_ml = models.BooleanField(default=True) class Post_and_pvzGroup(models.Model): @@ -158,7 +159,7 @@ class Post_and_pvzGroup(models.Model): on_delete=models.CASCADE) image = models.ImageField(blank=True, null=True, upload_to='post_and_pvz_group_images/', verbose_name='Картинка') visible = models.BooleanField(default=True) - inlude_in_ml = models.BooleanField(default=True) + include_in_ml = models.BooleanField(default=True) class OtherObjectsCategory(models.Model): diff --git a/service/signals.py b/service/signals.py index 3117610..f8ac95b 100644 --- a/service/signals.py +++ b/service/signals.py @@ -1,6 +1,12 @@ from django.contrib.auth.models import Group from rest_registration.signals import user_registered +from service.layer_service import LayerService +from service.models import Post_and_pvz, Post_and_pvzGroup, Post_and_pvzCategory, OtherObjects, OtherObjectsGroup, \ + OtherObjectsCategory +from django.db.models.signals import post_save +from django.dispatch import receiver + def user_created(sender, user, request, **kwargs): group = Group.objects.get(name='Зритель') @@ -9,3 +15,39 @@ def user_created(sender, user, request, **kwargs): user_registered.connect(user_created) + + +@receiver(post_save, sender=Post_and_pvz) +def post_pvz_handler(sender, instance, **kwargs): + LayerService().count_post_pvz_for_placementpoint(instance) + + +@receiver(post_save, sender=Post_and_pvzGroup) +def post_group_handler(sender, instance, **kwargs): + objects = Post_and_pvz.objects.filter(group=instance) + for obj in objects: + obj.include_in_ml = instance.include_in_ml + obj.visible = instance.visible + obj.save() + + +@receiver(post_save, sender=Post_and_pvzCategory) +def post_category_handler(sender, instance, **kwargs): + objects = Post_and_pvzGroup.objects.filter(category=instance) + for obj in objects: + obj.include_in_ml = instance.include_in_ml + obj.visible = instance.visible + obj.save() + + +@receiver(post_save, sender=OtherObjectsGroup) +def other_group_handler(sender, instance, **kwargs): + OtherObjects.objects.filter(group=instance).update(visible=instance.visible) + + +@receiver(post_save, sender=OtherObjectsCategory) +def other_category_handler(sender, instance, **kwargs): + objects = OtherObjectsGroup.objects.filter(category=instance) + for obj in objects: + obj.visible = instance.visible + obj.save() diff --git a/service/utils.py b/service/utils.py index 180cf83..539c148 100644 --- a/service/utils.py +++ b/service/utils.py @@ -1,3 +1,5 @@ +import os + import geojson import numpy as np import pandas as pd @@ -12,6 +14,25 @@ from django.conf import settings from rest_framework.response import Response from rest_framework.viewsets import ReadOnlyModelViewSet +import psycopg2 +from postamates.settings import DB_URL + + +def run_psql_command(): + connection = psycopg2.connect( + DB_URL + ) + try: + cursor = connection.cursor() + command = "CALL public.pivot_dist();" + cursor.execute(command) + connection.commit() + except psycopg2.Error as e: + print("Error executing command:", e) + finally: + cursor.close() + connection.close() + def load_ao_and_rayons( ao_filepath: str,