From 9f9bd971cf1dd228c5852146db271068780103a1 Mon Sep 17 00:00:00 2001 From: "descansodj@hotmail.it" <#git#87865#> Date: Fri, 23 Apr 2021 17:57:22 +0200 Subject: [PATCH] #27642 relation_types serializer, url, exception and get all api --- app/api/exceptions.py | 5 +++ app/api/models.py | 10 ++++-- app/api/serializers.py | 12 ++++++- app/api/urls.py | 5 +++ app/api/views/__init__.py | 1 + app/api/views/relation_types.py | 62 +++++++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 app/api/views/relation_types.py diff --git a/app/api/exceptions.py b/app/api/exceptions.py index f7b90052..8e3f3582 100644 --- a/app/api/exceptions.py +++ b/app/api/exceptions.py @@ -41,6 +41,11 @@ class LabelValidationError(APIException): default_detail = 'You cannot create a label with same name or shortcut key.' +class RelationTypesValidationError(APIException): + status_code = status.HTTP_400_BAD_REQUEST + default_detail = 'You cannot create a relation type with same name or color.' + + class RoleConstraintException(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = 'The project needs at least one administrator.' diff --git a/app/api/models.py b/app/api/models.py index 9fdaa41c..ce83c1c4 100644 --- a/app/api/models.py +++ b/app/api/models.py @@ -265,21 +265,27 @@ class SequenceAnnotation(Annotation): unique_together = ('document', 'user', 'label', 'start_offset', 'end_offset') -class AnnotationRelations: +class AnnotationRelations(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) timestamp = models.DateTimeField(auto_now_add=True) annotation_id_1 = models.IntegerField() annotation_id_2 = models.IntegerField() type = models.CharField(max_length=50) + def __str__(self): + return f"{self.annotation_id_1} - {self.annotation_id_2} - {type}" + class Meta: unique_together = ('timestamp', 'user', 'annotation_id_1', 'annotation_id_2', 'type') -class RelationTypes: +class RelationTypes(models.Model): color = models.TextField() name = models.TextField() + def __str__(self): + return self.name + class Meta: unique_together = ('color', 'name') diff --git a/app/api/serializers.py b/app/api/serializers.py index 4268f4c0..6ce6206d 100644 --- a/app/api/serializers.py +++ b/app/api/serializers.py @@ -10,7 +10,7 @@ from .models import (AutoLabelingConfig, Comment, Document, DocumentAnnotation, Label, Project, Role, RoleMapping, Seq2seqAnnotation, Seq2seqProject, SequenceAnnotation, SequenceLabelingProject, Speech2textAnnotation, - Speech2textProject, TextClassificationProject) + Speech2textProject, TextClassificationProject, RelationTypes) class UserSerializer(serializers.ModelSerializer): @@ -277,3 +277,13 @@ class AutoLabelingConfigSerializer(serializers.ModelSerializer): 'You need to correctly specify the required fields: {}'.format(required_fields) ) return data + + +class RelationTypesSerializer(serializers.ModelSerializer): + + def validate(self, attrs): + return super().validate(attrs) + + class Meta: + model = RelationTypes + fields = ('id', 'color', 'name') \ No newline at end of file diff --git a/app/api/urls.py b/app/api/urls.py index 06edc4ea..872c802c 100644 --- a/app/api/urls.py +++ b/app/api/urls.py @@ -168,6 +168,11 @@ urlpatterns = [ view=views.AutoLabelingConfigParameterTest.as_view(), name='auto_labeling_parameter_testing' ), + path( #TODO: questo va sotto urlpatterns_project e deve prendere un int:project_id> come sotto + route='relationtypes', + view=views.RelationTypesList.as_view(), + name='roles' + ), path( route='projects/', view=views.ProjectDetail.as_view(), diff --git a/app/api/views/__init__.py b/app/api/views/__init__.py index f33ef2a9..ea35446a 100644 --- a/app/api/views/__init__.py +++ b/app/api/views/__init__.py @@ -9,3 +9,4 @@ from .project import * from .role import * from .statistics import * from .user import * +from .relation_types import * diff --git a/app/api/views/relation_types.py b/app/api/views/relation_types.py new file mode 100644 index 00000000..4d369eaf --- /dev/null +++ b/app/api/views/relation_types.py @@ -0,0 +1,62 @@ +import json +import logging + +from django.db import IntegrityError, transaction +from django.shortcuts import get_object_or_404 +from rest_framework import generics, status +from rest_framework.exceptions import ParseError +from rest_framework.parsers import MultiPartParser +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView + +from ..exceptions import RelationTypesValidationError +from ..models import RelationTypes, Project +from ..permissions import IsInProjectReadOnlyOrAdmin, IsProjectAdmin +from ..serializers import RelationTypesSerializer + + +# class RelationTypesList(generics.ListCreateAPIView): +# serializer_class = RelationTypesSerializer +# pagination_class = None +# permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin] +# +# def get_queryset(self): +# project = get_object_or_404(Project, pk=self.kwargs['project_id']) +# return project.relation_types +# +# def perform_create(self, serializer): +# project = get_object_or_404(Project, pk=self.kwargs['project_id']) +# serializer.save(project=project) +# +# def delete(self, request, *args, **kwargs): +# delete_ids = request.data['ids'] +# RelationTypes.objects.filter(pk__in=delete_ids).delete() +# return Response(status=status.HTTP_204_NO_CONTENT) + + +class RelationTypesList(APIView): + permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin] + + def get(self, request, *args, **kwargs): + relation_types = RelationTypes.objects.all() + serializer = RelationTypesSerializer(relation_types, many=True) + return Response(serializer.data) + + @transaction.atomic + def post(self, request, *args, **kwargs): + if 'file' not in request.data: + raise ParseError('Empty content') + # project = get_object_or_404(Project, pk=kwargs['project_id']) + try: + logging.info(f"request.data:: {request.data}") + relation_type = json.load(request.data['relation_type']) + serializer = RelationTypesSerializer(relation_type, many=False) + serializer.is_valid(raise_exception=True) + # serializer.save(project=project) + serializer.save() + return Response(status=status.HTTP_201_CREATED) + except json.decoder.JSONDecodeError: + raise ParseError('The file format is invalid.') + except IntegrityError: + raise RelationTypesValidationError