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

  1. from functools import partial
  2. from django.core.exceptions import ValidationError
  3. from django.shortcuts import get_object_or_404
  4. from rest_framework import generics, status
  5. from rest_framework.permissions import IsAuthenticated
  6. from rest_framework.response import Response
  7. from api.models import Project
  8. from labels.models import Category, Span, TextLabel, Relation
  9. from members.permissions import IsInProjectOrAdmin, IsInProjectReadOnlyOrAdmin
  10. from .permissions import CanEditLabel
  11. from .serializers import CategorySerializer, SpanSerializer, TextLabelSerializer, RelationSerializer
  12. class BaseListAPI(generics.ListCreateAPIView):
  13. label_class = None
  14. pagination_class = None
  15. permission_classes = [IsAuthenticated & IsInProjectOrAdmin]
  16. swagger_schema = None
  17. @property
  18. def project(self):
  19. return get_object_or_404(Project, pk=self.kwargs['project_id'])
  20. def get_queryset(self):
  21. queryset = self.label_class.objects.filter(example=self.kwargs['example_id'])
  22. if not self.project.collaborative_annotation:
  23. queryset = queryset.filter(user=self.request.user)
  24. return queryset
  25. def create(self, request, *args, **kwargs):
  26. request.data['example'] = self.kwargs['example_id']
  27. try:
  28. response = super().create(request, args, kwargs)
  29. except ValidationError as err:
  30. response = Response({'detail': err.messages}, status=status.HTTP_400_BAD_REQUEST)
  31. return response
  32. def perform_create(self, serializer):
  33. serializer.save(example_id=self.kwargs['example_id'], user=self.request.user)
  34. def delete(self, request, *args, **kwargs):
  35. queryset = self.get_queryset()
  36. queryset.all().delete()
  37. return Response(status=status.HTTP_204_NO_CONTENT)
  38. class BaseDetailAPI(generics.RetrieveUpdateDestroyAPIView):
  39. lookup_url_kwarg = 'annotation_id'
  40. swagger_schema = None
  41. @property
  42. def project(self):
  43. return get_object_or_404(Project, pk=self.kwargs['project_id'])
  44. def get_permissions(self):
  45. if self.project.collaborative_annotation:
  46. self.permission_classes = [IsAuthenticated & IsInProjectOrAdmin]
  47. else:
  48. self.permission_classes = [
  49. IsAuthenticated & IsInProjectOrAdmin & partial(CanEditLabel, self.queryset)
  50. ]
  51. return super().get_permissions()
  52. class CategoryListAPI(BaseListAPI):
  53. label_class = Category
  54. serializer_class = CategorySerializer
  55. def create(self, request, *args, **kwargs):
  56. if self.project.single_class_classification:
  57. self.get_queryset().delete()
  58. return super().create(request, args, kwargs)
  59. class CategoryDetailAPI(BaseDetailAPI):
  60. queryset = Category.objects.all()
  61. serializer_class = CategorySerializer
  62. class SpanListAPI(BaseListAPI):
  63. label_class = Span
  64. serializer_class = SpanSerializer
  65. class SpanDetailAPI(BaseDetailAPI):
  66. queryset = Span.objects.all()
  67. serializer_class = SpanSerializer
  68. class TextLabelListAPI(BaseListAPI):
  69. label_class = TextLabel
  70. serializer_class = TextLabelSerializer
  71. class TextLabelDetailAPI(BaseDetailAPI):
  72. queryset = TextLabel.objects.all()
  73. serializer_class = TextLabelSerializer
  74. class RelationList(generics.ListCreateAPIView):
  75. serializer_class = RelationSerializer
  76. pagination_class = None
  77. permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin]
  78. def get_queryset(self):
  79. project = get_object_or_404(Project, pk=self.kwargs['project_id'])
  80. return project.annotation_relations
  81. def perform_create(self, serializer):
  82. project = get_object_or_404(Project, pk=self.kwargs['project_id'])
  83. serializer.save(project=project)
  84. def delete(self, request, *args, **kwargs):
  85. delete_ids = request.data['ids']
  86. Relation.objects.filter(pk__in=delete_ids).delete()
  87. return Response(status=status.HTTP_204_NO_CONTENT)
  88. class RelationDetail(generics.RetrieveUpdateDestroyAPIView):
  89. queryset = Relation.objects.all()
  90. serializer_class = RelationSerializer
  91. lookup_url_kwarg = 'annotation_id'
  92. permission_classes = [IsAuthenticated & IsInProjectReadOnlyOrAdmin]