F: Implement attribution merge on substitution
This commit is contained in:
parent
531bd0e3d2
commit
bfcc43457c
|
|
@ -12,6 +12,7 @@ from shared import messages as msg
|
|||
|
||||
from ..graph import Graph
|
||||
from .api_RSLanguage import get_type_prefix, guess_type
|
||||
from .Attribution import Attribution
|
||||
from .Constituenta import Constituenta, CstType, extract_entities, extract_globals
|
||||
|
||||
INSERT_LAST: int = -1
|
||||
|
|
@ -271,6 +272,25 @@ class RSForm:
|
|||
mapping[original.alias] = substitution.alias
|
||||
deleted.append(original.pk)
|
||||
replacements.append(substitution.pk)
|
||||
|
||||
attributions = list(Attribution.objects.filter(container__schema=self.model))
|
||||
if attributions:
|
||||
orig_to_sub = {original.pk: substitution.pk for original, substitution in substitutions}
|
||||
orig_pks = set(orig_to_sub.keys())
|
||||
|
||||
for attr in attributions:
|
||||
if attr.container_id not in orig_pks and attr.attribute_id not in orig_pks:
|
||||
continue
|
||||
|
||||
container_id = orig_to_sub.get(attr.container_id)
|
||||
container_id = container_id if container_id is not None else attr.container_id
|
||||
attr_id = orig_to_sub.get(attr.attribute_id)
|
||||
attr_id = attr_id if attr_id is not None else attr.attribute_id
|
||||
if not any(a.container_id == container_id and a.attribute_id == attr_id for a in attributions):
|
||||
attr.attribute_id = attr_id
|
||||
attr.container_id = container_id
|
||||
attr.save()
|
||||
|
||||
Constituenta.objects.filter(pk__in=deleted).delete()
|
||||
cst_list = Constituenta.objects.filter(schema=self.model).only(
|
||||
'alias', 'cst_type', 'definition_formal',
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from apps.library.models import LibraryItem, LibraryItemType
|
|||
from shared import messages as msg
|
||||
|
||||
from .api_RSLanguage import generate_structure, get_type_prefix, guess_type
|
||||
from .Attribution import Attribution
|
||||
from .Constituenta import Constituenta, CstType
|
||||
from .RSForm import DELETED_ALIAS, INSERT_LAST, RSForm
|
||||
|
||||
|
|
@ -149,6 +150,9 @@ class RSFormCached:
|
|||
position = position + 1
|
||||
|
||||
new_cst = Constituenta.objects.bulk_create(result)
|
||||
|
||||
# TODO: duplicate attributions
|
||||
|
||||
self.cache.insert_multi(new_cst)
|
||||
return result
|
||||
|
||||
|
|
@ -233,6 +237,25 @@ class RSFormCached:
|
|||
mapping[original.alias] = substitution.alias
|
||||
deleted.append(original)
|
||||
replacements.append(substitution.pk)
|
||||
|
||||
attributions = list(Attribution.objects.filter(container__schema=self.model))
|
||||
if attributions:
|
||||
orig_to_sub = {original.pk: substitution.pk for original, substitution in substitutions}
|
||||
orig_pks = set(orig_to_sub.keys())
|
||||
|
||||
for attr in attributions:
|
||||
if attr.container_id not in orig_pks and attr.attribute_id not in orig_pks:
|
||||
continue
|
||||
|
||||
container_id = orig_to_sub.get(attr.container_id)
|
||||
container_id = container_id if container_id is not None else attr.container_id
|
||||
attr_id = orig_to_sub.get(attr.attribute_id)
|
||||
attr_id = attr_id if attr_id is not None else attr.attribute_id
|
||||
if not any(a.container_id == container_id and a.attribute_id == attr_id for a in attributions):
|
||||
attr.attribute_id = attr_id
|
||||
attr.container_id = container_id
|
||||
attr.save()
|
||||
|
||||
self.cache.remove_multi(deleted)
|
||||
Constituenta.objects.filter(pk__in=[cst.pk for cst in deleted]).delete()
|
||||
RSForm.save_order(self.cache.constituents)
|
||||
|
|
|
|||
|
|
@ -238,11 +238,55 @@ class TestRSFormViewset(EndpointTester):
|
|||
'substitution': d2.pk
|
||||
}
|
||||
]}
|
||||
response = self.executeOK(data, item=self.owned_id)
|
||||
self.executeOK(data, item=self.owned_id)
|
||||
d3.refresh_from_db()
|
||||
self.assertEqual(d3.definition_formal, r'D1 \ D2')
|
||||
|
||||
|
||||
@decl_endpoint('/api/rsforms/{item}/substitute', method='patch')
|
||||
def test_substitute_with_attributions(self):
|
||||
self.set_params(item=self.owned_id)
|
||||
|
||||
# Create two base items
|
||||
x1 = self.owned.insert_last('X1')
|
||||
x2 = self.owned.insert_last('X2')
|
||||
|
||||
# Create two attributes to be attributions
|
||||
a1 = self.owned.insert_last('A1', cst_type=CstType.BASE)
|
||||
a2 = self.owned.insert_last('A2', cst_type=CstType.BASE)
|
||||
|
||||
# Create attributions: X1 -> A1, X2 -> A2
|
||||
Attribution = self.owned.constituentsQ().model._meta.apps.get_model('rsform', 'Attribution')
|
||||
Attribution.objects.create(container=x1, attribute=a1)
|
||||
Attribution.objects.create(container=x2, attribute=a2)
|
||||
|
||||
# Substitute x1 with x2
|
||||
data = {
|
||||
'substitutions': [{
|
||||
'original': x1.pk,
|
||||
'substitution': x2.pk
|
||||
}]
|
||||
}
|
||||
self.executeOK(data, item=self.owned_id)
|
||||
|
||||
# Fetch updated attributions
|
||||
attributions = Attribution.objects.filter(
|
||||
container__in=[x1.pk, x2.pk],
|
||||
attribute__in=[a1.pk, a2.pk]
|
||||
)
|
||||
self.assertEqual(len(attributions), 2)
|
||||
|
||||
# Confirm the attribution with container originally x1 is now x2, and there are no duplicates
|
||||
containers = set()
|
||||
attributes = set()
|
||||
for attr in attributions:
|
||||
containers.add(attr.container_id)
|
||||
attributes.add(attr.attribute_id)
|
||||
self.assertIn(x2.pk, containers)
|
||||
self.assertIn(a1.pk, attributes)
|
||||
self.assertIn(a2.pk, attributes)
|
||||
|
||||
|
||||
@decl_endpoint('/api/rsforms/{item}/create-cst', method='post')
|
||||
def test_create_constituenta_data(self):
|
||||
data = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user