You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

125 lines
4.1 KiB

from functools import partial
from django.core.exceptions import ValidationError
from django.shortcuts import get_object_or_404
from rest_framework import generics, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from api.models import Project
from labels.models import Category, Span, TextLabel, Relation
from members.permissions import IsInProjectOrAdmin, IsInProjectReadOnlyOrAdmin
from .permissions import CanEditLabel
from .serializers import CategorySerializer, SpanSerializer, TextLabelSerializer, RelationSerializer
class BaseListAPI(generics.ListCreateAPIView):
label_class = None
pagination_class = None
permission_classes = [IsAuthenticated & IsInProjectOrAdmin]
swagger_schema = None
@property
def project(self):
return get_object_or_404(Project, pk=self.kwargs['project_id'])
def get_queryset(self):
queryset = self.label_class.objects.filter(example=self.kwargs['example_id'])
if not self.project.collaborative_annotation:
queryset = queryset.filter(user=self.request.user)
return queryset
def create(self, request, *args, **kwargs):
request.data['example'] = self.kwargs['example_id']
try:
response = super().create(request, args, kwargs)
except ValidationError as err:
response = Response({'detail': err.messages}, status=status.HTTP_400_BAD_REQUEST)
return response
def perform_create(self, serializer):
serializer.save(example_id=self.kwargs['example_id'], user=self.request.user)
def delete(self, request, *args, **kwargs):
queryset = self.get_queryset()
queryset.all().delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class BaseDetailAPI(generics.RetrieveUpdateDestroyAPIView):
lookup_url_kwarg = 'annotation_id'
swagger_schema = None
@property
def project(self):
return get_object_or_404(Project, pk=self.kwargs['project_id'])
def get_permissions(self):
if self.project.collaborative_annotation:
self.permission_classes = [IsAuthenticated & IsInProjectOrAdmin]
else:
self.permission_classes = [
IsAuthenticated & IsInProjectOrAdmin & partial(CanEditLabel, self.queryset)
]
return super().get_permissions()
class CategoryListAPI(BaseListAPI):
label_class = Category
serializer_class = CategorySerializer
def create(self, request, *args, **kwargs):
if self.project.single_class_classification:
self.get_queryset().delete()
return super().create(request, args, kwargs)
class CategoryDetailAPI(BaseDetailAPI):
queryset = Category.objects.all()
serializer_class = CategorySerializer
class SpanListAPI(BaseListAPI):
label_class = Span
serializer_class = SpanSerializer
class SpanDetailAPI(BaseDetailAPI):
queryset = Span.objects.all()
serializer_class = SpanSerializer
class TextLabelListAPI(BaseListAPI):
label_class = TextLabel
serializer_class = TextLabelSerializer
class TextLabelDetailAPI(BaseDetailAPI):
queryset = TextLabel.objects.all()
serializer_class = TextLabelSerializer
class RelationList(generics.ListCreateAPIView):
serializer_class = RelationSerializer
pagination_class = None
permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin]
def get_queryset(self):
project = get_object_or_404(Project, pk=self.kwargs['project_id'])
return project.annotation_relations
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']
Relation.objects.filter(pk__in=delete_ids).delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class RelationDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Relation.objects.all()
serializer_class = RelationSerializer
lookup_url_kwarg = 'annotation_id'
permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin]