B: Copy attributions when cloning

This commit is contained in:
Ivan 2025-08-23 16:04:54 +03:00
parent 1555a1bf92
commit c358415642
2 changed files with 17 additions and 3 deletions

View File

@ -9,7 +9,7 @@ from apps.library.models import (
LibraryTemplate,
LocationHead
)
from apps.rsform.models import RSForm
from apps.rsform.models import Attribution, RSForm
from shared.EndpointTester import EndpointTester, decl_endpoint
from shared.testing_utils import response_contains
@ -343,6 +343,7 @@ class TestLibraryViewset(EndpointTester):
term_raw='@{X12|plur}',
term_resolved='люди'
)
Attribution.objects.create(container=d2, attribute=x12)
data = {'item_data': {'title': 'Title1337'}, 'items': []}
self.executeNotFound(data, item=self.invalid_item)
@ -351,6 +352,7 @@ class TestLibraryViewset(EndpointTester):
response = self.executeCreated(data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['item_data']['title'])
self.assertEqual(len(response.data['items']), 2)
self.assertEqual(len(response.data['attribution']), 1)
self.assertEqual(response.data['items'][0]['alias'], x12.alias)
self.assertEqual(response.data['items'][0]['term_raw'], x12.term_raw)
self.assertEqual(response.data['items'][0]['term_resolved'], x12.term_resolved)

View File

@ -14,7 +14,7 @@ from rest_framework.request import Request
from rest_framework.response import Response
from apps.oss.models import Layout, Operation, OperationSchema, PropagationFacade
from apps.rsform.models import RSFormCached
from apps.rsform.models import Attribution, RSFormCached
from apps.rsform.serializers import RSFormParseSerializer
from apps.users.models import User
from shared import permissions
@ -157,8 +157,8 @@ class LibraryViewSet(viewsets.ModelViewSet):
serializer = s.LibraryItemCloneSerializer(data=request.data, context={'schema': item})
serializer.is_valid(raise_exception=True)
data = serializer.validated_data['item_data']
with transaction.atomic():
clone = deepcopy(item)
clone.pk = None
@ -171,12 +171,24 @@ class LibraryViewSet(viewsets.ModelViewSet):
clone.access_policy = data.get('access_policy', m.AccessPolicy.PUBLIC)
clone.location = data.get('location', m.LocationHead.USER)
clone.save()
cst_map: dict[int, int] = {}
cst_list: list[int] = []
need_filter = 'items' in request.data and request.data['items']
for cst in RSFormCached(item).constituentsQ():
if not need_filter or cst.pk in request.data['items']:
old_pk = cst.pk
cst.pk = None
cst.schema = clone
cst.save()
cst_map[old_pk] = cst.pk
cst_list.append(old_pk)
for attr in Attribution.objects.filter(container__in=cst_list, attribute__in=cst_list):
attr.pk = None
attr.container_id = cst_map[attr.container_id]
attr.attribute_id = cst_map[attr.attribute_id]
attr.save()
return Response(
status=c.HTTP_201_CREATED,
data=RSFormParseSerializer(clone).data