iac/apps/eav/asterus/asset.yaml
2026-09-23 23:36:27 +05:00

161 lines
6.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

apiVersion: v1
data:
asset.py: |
from typing import List
from django.conf import settings
from django.http import HttpResponseBadRequest
from django_filters import rest_framework as django_filters
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import filters
from rest_framework.viewsets import ModelViewSet
from assets.api.v0.filters.asset import AssetFilter
from assets.models import Asset
from assets.serializers import (
AssetSerializer,
AssetSearchSerializer,
# AssetCopySerializer,
AssetCopyRequestSerializer,
)
from core.permissions import CompanyIdTokenBasedPermission
class AssetViewSet(ModelViewSet):
queryset = Asset.objects.all()
filterset_class = AssetFilter
filter_backends = (django_filters.DjangoFilterBackend, filters.OrderingFilter, )
serializer_class = AssetSerializer
topic = settings.ASSETS_TOPIC
permission_classes = [CompanyIdTokenBasedPermission, ]
ordering_fields = ['created_at', 'name']
ordering = ['-created_at']
def get_queryset(self):
validated_token = self.request.auth
print(self.request.auth)
#user_company_ids = validated_token.get("company_ids")
is_superuser = True
if is_superuser:
return Asset.objects.all()
return Asset.objects.filter(
tenant_id__in=1,
)
def get_serializer(self, *args, **kwargs):
if isinstance(kwargs.get("data", {}), list):
kwargs["many"] = True
return super().get_serializer(*args, **kwargs)
def list_update(self, request, *args, **kwargs):
instances = self.get_queryset().filter(id__in=[item.get('id') for item in request.data])
serializer = self.serializer_class(instances, data=request.data, many=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
def list_partial_update(self, request, *args, **kwargs):
instances = self.get_queryset().filter(id__in=[item.get('id') for item in request.data])
serializer = self.serializer_class(instances, data=request.data, many=True, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
def destroy(self, request, *args, **kwargs):
serializer = self.get_serializer()
parent = self.get_object()
instances = self.queryset.filter(path__icontains=parent.id)
for i in instances:
serializer.destroy(i)
return Response(None, status=status.HTTP_200_OK)
@action(detail=True, methods=['post'])
def copy(self, request, *args, **kwargs):
serializer = self.get_serializer()
request_serializer = AssetCopyRequestSerializer(data=request.data)
source = self.get_object()
if source.parent_id:
return HttpResponseBadRequest("Only root assets are allowed")
request_serializer.is_valid(raise_exception=True)
if request_serializer.validated_data["recursive"]:
name = request_serializer.validated_data["destination"]["name"] if \
request_serializer.validated_data["destination"]["name"] else source.name
destination = self.copy_recursive(source.id, name,
request_serializer.validated_data["destination"]["resource_id"])
else:
destination = serializer.copy(source, request_serializer.validated_data["destination"])
return Response(AssetSerializer(destination).data, status=status.HTTP_201_CREATED)
def copy_recursive(self, root_id: int, root_name: str, resource_id: str) -> Asset:
root_copy = None
serializer = self.get_serializer()
copies_map = {}
# Мы должны гарантировать, что дочерние ноды будут созданы в базе не раньше родительских
sorted_nodes = self.sort_nodes(root_id)
for source in sorted_nodes:
# Установить имя копии как у оригинала, но в случае рута - целевое имя
if source.parent_id:
copy_data = {
"name": source.name,
"parent_id": copies_map[source.parent_id],
"resource_id": resource_id
}
destination = serializer.copy(source, copy_data)
else:
copy_data = {
"name": root_name,
"parent_id": None,
"resource_id": resource_id
}
destination = serializer.copy(source, copy_data)
root_copy = destination
copies_map[source.id] = destination.id
return root_copy
def sort_nodes(self, root_id: int) -> List[Asset]:
nodes_instances = self.queryset.filter(path__icontains=root_id)
sort_dict = {}
sorted_nodes = []
for node in nodes_instances:
# Так как копировать можно только руты, уровень вложенности можно посчитать по количеству точек в пути
node_level = node.path.count('.')
if node_level not in sort_dict:
sort_dict[node_level] = []
sort_dict[node_level].append(node)
current_level = 0
while current_level in sort_dict:
sorted_nodes.extend(sort_dict[current_level])
current_level += 1
return sorted_nodes
@action(detail=False, methods=["POST"])
def search(self, request, *args, **kwargs):
request_serializer = AssetSearchSerializer(data=request.data)
request_serializer.is_valid(raise_exception=True)
instances = self.get_queryset()
if request_serializer.data["id"]:
instances = instances.filter(id__in=request_serializer.data["id"])
serializer = self.serializer_class(instances, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
kind: ConfigMap
metadata:
name: asset
namespace: eav