diff --git a/README.md b/README.md index ea99477d..a6b96af3 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ This readme file is used mostly to document project dependencies - Pylint - Django - autopep8 + - SQLite diff --git a/rsconcept/backend/apps/rsform/models/LibraryItem.py b/rsconcept/backend/apps/rsform/models/LibraryItem.py index 56813796..70489f9c 100644 --- a/rsconcept/backend/apps/rsform/models/LibraryItem.py +++ b/rsconcept/backend/apps/rsform/models/LibraryItem.py @@ -23,7 +23,7 @@ from .Version import Version class LibraryItemType(TextChoices): ''' Type of library items ''' RSFORM = 'rsform' - OPERATIONS_SCHEMA = 'oss' + OPERATION_SCHEMA = 'oss' class AccessPolicy(TextChoices): @@ -115,7 +115,7 @@ class LibraryItem(Model): def subscribers(self) -> list[Subscription]: ''' Get all subscribers for this item. ''' - return [subscription.user for subscription in Subscription.objects.filter(item=self.pk)] + return [subscription.user for subscription in Subscription.objects.filter(item=self.pk).only('user')] def versions(self) -> list[Version]: ''' Get all Versions of this item. ''' @@ -123,7 +123,7 @@ class LibraryItem(Model): def editors(self) -> list[Editor]: ''' Get all Editors of this item. ''' - return [item.editor for item in Editor.objects.filter(item=self.pk)] + return [item.editor for item in Editor.objects.filter(item=self.pk).only('editor')] @transaction.atomic def save(self, *args, **kwargs): diff --git a/rsconcept/backend/apps/rsform/models/api_RSForm.py b/rsconcept/backend/apps/rsform/models/api_RSForm.py index 45ee0ffb..dee2f7e6 100644 --- a/rsconcept/backend/apps/rsform/models/api_RSForm.py +++ b/rsconcept/backend/apps/rsform/models/api_RSForm.py @@ -105,13 +105,12 @@ class RSForm: return result @transaction.atomic - def create_cst(self, data: dict, insert_after: Optional[str] = None) -> Constituenta: + def create_cst(self, data: dict, insert_after: Optional[Constituenta] = None) -> Constituenta: ''' Create new cst from data. ''' if insert_after is None: position = _INSERT_LAST else: - cst_after = Constituenta.objects.get(pk=insert_after) - position = cst_after.order + 1 + position = insert_after.order + 1 result = self.insert_new(data['alias'], data['cst_type'], position) result.convention = data.get('convention', '') result.definition_formal = data.get('definition_formal', '') diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py index 7881f2b9..195bb080 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py +++ b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py @@ -101,6 +101,26 @@ class TestRSForm(TestCase): self.assertEqual(x2.schema, self.schema.item) self.assertEqual(x1.order, 1) + def test_create_cst(self): + data = { + 'alias': 'X3', + 'cst_type': CstType.BASE, + 'term_raw': 'слон', + 'definition_raw': 'test', + 'convention': 'convention' + } + + x1 = self.schema.insert_new('X1') + x2 = self.schema.insert_new('X2') + x3 = self.schema.create_cst(data=data, insert_after=x1) + x2.refresh_from_db() + + self.assertEqual(x3.alias, data['alias']) + self.assertEqual(x3.term_raw, data['term_raw']) + self.assertEqual(x3.definition_raw, data['definition_raw']) + self.assertEqual(x2.order, 3) + self.assertEqual(x3.order, 2) + def test_create_cst_resolve(self): x1 = self.schema.insert_new( diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py index 3c53d80e..fcd92781 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py @@ -52,7 +52,7 @@ class TestLibraryViewset(EndpointTester): self.executeBadData(data) data = { - 'item_type': LibraryItemType.OPERATIONS_SCHEMA, + 'item_type': LibraryItemType.OPERATION_SCHEMA, 'title': 'Title', 'alias': 'alias', 'access_policy': AccessPolicy.PROTECTED, @@ -294,7 +294,7 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library', method='get') def test_library_get(self): non_schema = LibraryItem.objects.create( - item_type=LibraryItemType.OPERATIONS_SCHEMA, + item_type=LibraryItemType.OPERATION_SCHEMA, title='Test4' ) response = self.executeOK() diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py index dc735490..ac385761 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py @@ -59,7 +59,7 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms', method='get') def test_list_rsforms(self): non_schema = LibraryItem.objects.create( - item_type=LibraryItemType.OPERATIONS_SCHEMA, + item_type=LibraryItemType.OPERATION_SCHEMA, title='Test3' ) response = self.executeOK() diff --git a/rsconcept/backend/apps/rsform/views/rsforms.py b/rsconcept/backend/apps/rsform/views/rsforms.py index 1af946f1..65136f53 100644 --- a/rsconcept/backend/apps/rsform/views/rsforms.py +++ b/rsconcept/backend/apps/rsform/views/rsforms.py @@ -60,10 +60,15 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr serializer = s.CstCreateSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.validated_data - new_cst = schema.create_cst( - data=data, - insert_after=data['insert_after'] if 'insert_after' in data else None - ) + if 'insert_after' in data: + try: + insert_after = m.Constituenta.objects.get(pk=data['insert_after']) + except m.LibraryItem.DoesNotExist: + return Response(status=c.HTTP_404_NOT_FOUND) + else: + insert_after = None + new_cst = schema.create_cst(data, insert_after) + schema.item.refresh_from_db() response = Response( status=c.HTTP_201_CREATED, @@ -313,7 +318,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr c.HTTP_404_NOT_FOUND: None } ) - @action(detail=True, methods=['get']) + @action(detail=True, methods=['get'], url_path='contents') def contents(self, request: Request, pk): ''' Endpoint: View schema db contents (including constituents). ''' schema = s.RSFormSerializer(self.get_object()) @@ -331,7 +336,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr c.HTTP_404_NOT_FOUND: None } ) - @action(detail=True, methods=['get']) + @action(detail=True, methods=['get'], url_path='details') def details(self, request: Request, pk): ''' Endpoint: Detailed schema view including statuses and parse. ''' serializer = s.RSFormParseSerializer(cast(m.LibraryItem, self.get_object())) @@ -349,7 +354,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr c.HTTP_404_NOT_FOUND: None }, ) - @action(detail=True, methods=['post']) + @action(detail=True, methods=['post'], url_path='check') def check(self, request: Request, pk): ''' Endpoint: Check RSLang expression against schema context. ''' serializer = s.ExpressionSerializer(data=request.data) @@ -371,7 +376,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr c.HTTP_404_NOT_FOUND: None } ) - @action(detail=True, methods=['post']) + @action(detail=True, methods=['post'], url_path='resolve') def resolve(self, request: Request, pk): ''' Endpoint: Resolve references in text against schema terms context. ''' serializer = s.TextSerializer(data=request.data) diff --git a/rsconcept/backend/fixtures/InitialData.json b/rsconcept/backend/fixtures/InitialData.json index ee9dd19c..cfb7982c 100644 --- a/rsconcept/backend/fixtures/InitialData.json +++ b/rsconcept/backend/fixtures/InitialData.json @@ -1,4 +1,22 @@ [ +{ + "model": "auth.user", + "pk": 1, + "fields": { + "password": "pbkdf2_sha256$720000$gFZkaBswurtL0naQKiUnW7$3b6SUN3fY2Xl1H7erAszVpQl2LpoKusan+yJP7Bp3JA=", + "last_login": "2024-06-03T20:57:02.522Z", + "is_superuser": true, + "username": "admin", + "first_name": "Администратор", + "last_name": "", + "email": "admin@mail.ru", + "is_staff": true, + "is_active": true, + "date_joined": "2024-05-27T18:31:48.913Z", + "groups": [], + "user_permissions": [] + } +}, { "model": "auth.user", "pk": 3,