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.

207 lines
7.7 KiB

6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
  1. from django.conf import settings
  2. from django.contrib.auth import get_user_model
  3. from django.shortcuts import get_object_or_404
  4. from rest_framework import serializers
  5. from rest_polymorphic.serializers import PolymorphicSerializer
  6. from rest_framework.exceptions import ValidationError
  7. from .models import Label, Project, Document, RoleMapping, Role
  8. from .models import TextClassificationProject, SequenceLabelingProject, Seq2seqProject
  9. from .models import DocumentAnnotation, SequenceAnnotation, Seq2seqAnnotation
  10. class UserSerializer(serializers.ModelSerializer):
  11. class Meta:
  12. model = get_user_model()
  13. fields = ('id', 'username', 'first_name', 'last_name', 'email', 'is_superuser')
  14. class LabelSerializer(serializers.ModelSerializer):
  15. def validate(self, attrs):
  16. if 'prefix_key' not in attrs and 'suffix_key' not in attrs:
  17. return super().validate(attrs)
  18. prefix_key = attrs['prefix_key']
  19. suffix_key = attrs['suffix_key']
  20. # In the case of user don't set any shortcut key.
  21. if prefix_key is None and suffix_key is None:
  22. return super().validate(attrs)
  23. # Don't allow shortcut key not to have a suffix key.
  24. if prefix_key and not suffix_key:
  25. raise ValidationError('Shortcut key may not have a suffix key.')
  26. # Don't allow to save same shortcut key when prefix_key is null.
  27. try:
  28. context = self.context['request'].parser_context
  29. project_id = context['kwargs']['project_id']
  30. except (AttributeError, KeyError):
  31. pass # unit tests don't always have the correct context set up
  32. else:
  33. if Label.objects.filter(suffix_key=suffix_key,
  34. prefix_key=prefix_key,
  35. project=project_id).exists():
  36. raise ValidationError('Duplicate key.')
  37. return super().validate(attrs)
  38. class Meta:
  39. model = Label
  40. fields = ('id', 'text', 'prefix_key', 'suffix_key', 'background_color', 'text_color')
  41. class DocumentSerializer(serializers.ModelSerializer):
  42. annotations = serializers.SerializerMethodField()
  43. annotation_approver = serializers.SerializerMethodField()
  44. def get_annotations(self, instance):
  45. request = self.context.get('request')
  46. project = instance.project
  47. model = project.get_annotation_class()
  48. serializer = project.get_annotation_serializer()
  49. annotations = model.objects.filter(document=instance.id)
  50. if request and not project.collaborative_annotation:
  51. annotations = annotations.filter(user=request.user)
  52. serializer = serializer(annotations, many=True)
  53. return serializer.data
  54. @classmethod
  55. def get_annotation_approver(cls, instance):
  56. approver = instance.annotations_approved_by
  57. return approver.username if approver else None
  58. class Meta:
  59. model = Document
  60. fields = ('id', 'text', 'annotations', 'meta', 'annotation_approver')
  61. class ProjectSerializer(serializers.ModelSerializer):
  62. current_users_role = serializers.SerializerMethodField()
  63. def get_current_users_role(self, instance):
  64. role_abstractor = {
  65. "is_project_admin": settings.ROLE_PROJECT_ADMIN,
  66. "is_annotator": settings.ROLE_ANNOTATOR,
  67. "is_annotation_approver": settings.ROLE_ANNOTATION_APPROVER,
  68. }
  69. queryset = RoleMapping.objects.values("role_id__name")
  70. if queryset:
  71. users_role = get_object_or_404(
  72. queryset, project=instance.id, user=self.context.get("request").user.id
  73. )
  74. for key, val in role_abstractor.items():
  75. role_abstractor[key] = users_role["role_id__name"] == val
  76. return role_abstractor
  77. class Meta:
  78. model = Project
  79. fields = ('id', 'name', 'description', 'guideline', 'users', 'current_users_role', 'project_type', 'image',
  80. 'updated_at', 'randomize_document_order', 'collaborative_annotation')
  81. read_only_fields = ('image', 'updated_at', 'current_users_role')
  82. class TextClassificationProjectSerializer(ProjectSerializer):
  83. class Meta:
  84. model = TextClassificationProject
  85. fields = ('id', 'name', 'description', 'guideline', 'users', 'current_users_role', 'project_type', 'image',
  86. 'updated_at', 'randomize_document_order')
  87. read_only_fields = ('image', 'updated_at', 'users', 'current_users_role')
  88. class SequenceLabelingProjectSerializer(ProjectSerializer):
  89. class Meta:
  90. model = SequenceLabelingProject
  91. fields = ('id', 'name', 'description', 'guideline', 'users', 'current_users_role', 'project_type', 'image',
  92. 'updated_at', 'randomize_document_order')
  93. read_only_fields = ('image', 'updated_at', 'users', 'current_users_role')
  94. class Seq2seqProjectSerializer(ProjectSerializer):
  95. class Meta:
  96. model = Seq2seqProject
  97. fields = ('id', 'name', 'description', 'guideline', 'users', 'current_users_role', 'project_type', 'image',
  98. 'updated_at', 'randomize_document_order')
  99. read_only_fields = ('image', 'updated_at', 'users', 'current_users_role')
  100. class ProjectPolymorphicSerializer(PolymorphicSerializer):
  101. model_serializer_mapping = {
  102. Project: ProjectSerializer,
  103. TextClassificationProject: TextClassificationProjectSerializer,
  104. SequenceLabelingProject: SequenceLabelingProjectSerializer,
  105. Seq2seqProject: Seq2seqProjectSerializer
  106. }
  107. class ProjectFilteredPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):
  108. def get_queryset(self):
  109. view = self.context.get('view', None)
  110. request = self.context.get('request', None)
  111. queryset = super(ProjectFilteredPrimaryKeyRelatedField, self).get_queryset()
  112. if not request or not queryset or not view:
  113. return None
  114. return queryset.filter(project=view.kwargs['project_id'])
  115. class DocumentAnnotationSerializer(serializers.ModelSerializer):
  116. # label = ProjectFilteredPrimaryKeyRelatedField(queryset=Label.objects.all())
  117. label = serializers.PrimaryKeyRelatedField(queryset=Label.objects.all())
  118. document = serializers.PrimaryKeyRelatedField(queryset=Document.objects.all())
  119. class Meta:
  120. model = DocumentAnnotation
  121. fields = ('id', 'prob', 'label', 'user', 'document')
  122. read_only_fields = ('user', )
  123. class SequenceAnnotationSerializer(serializers.ModelSerializer):
  124. #label = ProjectFilteredPrimaryKeyRelatedField(queryset=Label.objects.all())
  125. label = serializers.PrimaryKeyRelatedField(queryset=Label.objects.all())
  126. document = serializers.PrimaryKeyRelatedField(queryset=Document.objects.all())
  127. class Meta:
  128. model = SequenceAnnotation
  129. fields = ('id', 'prob', 'label', 'start_offset', 'end_offset', 'user', 'document')
  130. read_only_fields = ('user',)
  131. class Seq2seqAnnotationSerializer(serializers.ModelSerializer):
  132. document = serializers.PrimaryKeyRelatedField(queryset=Document.objects.all())
  133. class Meta:
  134. model = Seq2seqAnnotation
  135. fields = ('id', 'text', 'user', 'document', 'prob')
  136. read_only_fields = ('user',)
  137. class RoleSerializer(serializers.ModelSerializer):
  138. class Meta:
  139. model = Role
  140. fields = ('id', 'name')
  141. class RoleMappingSerializer(serializers.ModelSerializer):
  142. username = serializers.SerializerMethodField()
  143. rolename = serializers.SerializerMethodField()
  144. @classmethod
  145. def get_username(cls, instance):
  146. user = instance.user
  147. return user.username if user else None
  148. @classmethod
  149. def get_rolename(cls, instance):
  150. role = instance.role
  151. return role.name if role else None
  152. class Meta:
  153. model = RoleMapping
  154. fields = ('id', 'user', 'role', 'username', 'rolename')