Implement InlineSynthesis backend

This commit is contained in:
IRBorisov 2024-03-22 20:14:32 +03:00
parent 68b6891ae4
commit a47d93a59b
3 changed files with 63 additions and 7 deletions

View File

@ -4,6 +4,12 @@
def constituentaNotOwned(title: str):
return f'Конституента не принадлежит схеме: {title}'
def substitutionNotInList():
return 'Отождествляемая конституента отсутствует в списке'
def schemaNotOwned():
return 'Нет доступа к схеме'
def renameTrivial(name: str):
return f'Имя должно отличаться от текущего: {name}'

View File

@ -1,5 +1,7 @@
''' Serializers for persistent data manipulation. '''
from typing import Optional, cast
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from rest_framework import serializers
from rest_framework.serializers import PrimaryKeyRelatedField as PKField
@ -297,4 +299,39 @@ class InlineSynthesisSerializer(serializers.Serializer):
)
def validate(self, attrs):
user = cast(User, self.context['user'])
schema_in = cast(LibraryItem, attrs['source'])
schema_out = cast(LibraryItem, attrs['receiver'])
if user.is_anonymous or (schema_out.owner != user and not user.is_staff):
raise PermissionDenied({
'message': msg.schemaNotOwned(),
'object_id': schema_in.id
})
constituents = cast(list[Constituenta], attrs['items'])
for cst in constituents:
if cst.schema != schema_in:
raise serializers.ValidationError({
f'{cst.id}': msg.constituentaNotOwned(schema_in.title)
})
for item in attrs['substitutions']:
original_cst = cast(Constituenta, item['original'])
substitution_cst = cast(Constituenta, item['substitution'])
if original_cst.schema == schema_in:
if original_cst not in constituents:
raise serializers.ValidationError({
f'{original_cst.id}': msg.substitutionNotInList()
})
if substitution_cst.schema != schema_out:
raise serializers.ValidationError({
f'{substitution_cst.id}': msg.constituentaNotOwned(schema_out.title)
})
else:
if substitution_cst not in constituents:
raise serializers.ValidationError({
f'{substitution_cst.id}': msg.substitutionNotInList()
})
if original_cst.schema != schema_out:
raise serializers.ValidationError({
f'{original_cst.id}': msg.constituentaNotOwned(schema_out.title)
})
return attrs

View File

@ -1,4 +1,6 @@
''' Endpoints for RSForm. '''
from typing import cast
from django.db import transaction
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.request import Request
@ -14,19 +16,30 @@ from .. import serializers as s
request=s.InlineSynthesisSerializer,
responses={c.HTTP_200_OK: s.RSFormParseSerializer}
)
@transaction.atomic
@api_view(['PATCH'])
def inline_synthesis(request: Request):
''' Endpoint: Inline synthesis. '''
serializer = s.InlineSynthesisSerializer(data=request.data)
serializer = s.InlineSynthesisSerializer(
data=request.data,
context={'user': request.user}
)
serializer.is_valid(raise_exception=True)
schema = m.RSForm(serializer.validated_data['receiver'])
# schema.substitute(
# original=serializer.validated_data['original'],
# substitution=serializer.validated_data['substitution'],
# transfer_term=serializer.validated_data['transfer_term']
# )
schema.item.refresh_from_db()
items = cast(list[m.Constituenta], serializer.validated_data['items'])
new_items = schema.insert_copy(items)
for substitution in serializer.validated_data['substitutions']:
original = cast(m.Constituenta, substitution['original'])
replacement = cast(m.Constituenta, substitution['substitution'])
if original in items:
index = next(i for (i, cst) in enumerate(items) if cst == original)
original = new_items[index]
else:
index = next(i for (i, cst) in enumerate(items) if cst == replacement)
replacement = new_items[index]
schema.substitute(original, replacement, serializer.validated_data['transfer_term'])
return Response(
status=c.HTTP_200_OK,
data=s.RSFormParseSerializer(schema.item).data