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.

301 lines
8.2 KiB

6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
3 years ago
  1. from rest_framework import serializers
  2. from rest_framework.exceptions import ValidationError
  3. from rest_polymorphic.serializers import PolymorphicSerializer
  4. from .models import (AnnotationRelations, Category, CategoryType, Comment,
  5. Example, ExampleState, ImageClassificationProject,
  6. IntentDetectionAndSlotFillingProject, Label, Project,
  7. RelationTypes, Seq2seqProject, SequenceLabelingProject,
  8. Span, SpanType, Speech2textProject, Tag,
  9. TextClassificationProject, TextLabel)
  10. class LabelSerializer(serializers.ModelSerializer):
  11. def validate(self, attrs):
  12. prefix_key = attrs.get('prefix_key')
  13. suffix_key = attrs.get('suffix_key')
  14. # In the case of user don't set any shortcut key.
  15. if prefix_key is None and suffix_key is None:
  16. return super().validate(attrs)
  17. # Don't allow shortcut key not to have a suffix key.
  18. if prefix_key and not suffix_key:
  19. raise ValidationError('Shortcut key may not have a suffix key.')
  20. # Don't allow to save same shortcut key when prefix_key is null.
  21. try:
  22. context = self.context['request'].parser_context
  23. project_id = context['kwargs']['project_id']
  24. label_id = context['kwargs'].get('label_id')
  25. except (AttributeError, KeyError):
  26. pass # unit tests don't always have the correct context set up
  27. else:
  28. conflicting_labels = self.Meta.model.objects.filter(
  29. suffix_key=suffix_key,
  30. prefix_key=prefix_key,
  31. project=project_id,
  32. )
  33. if label_id is not None:
  34. conflicting_labels = conflicting_labels.exclude(id=label_id)
  35. if conflicting_labels.exists():
  36. raise ValidationError('Duplicate shortcut key.')
  37. return super().validate(attrs)
  38. class Meta:
  39. model = Label
  40. fields = (
  41. 'id',
  42. 'text',
  43. 'prefix_key',
  44. 'suffix_key',
  45. 'background_color',
  46. 'text_color',
  47. )
  48. class CategoryTypeSerializer(LabelSerializer):
  49. class Meta:
  50. model = CategoryType
  51. fields = (
  52. 'id',
  53. 'text',
  54. 'prefix_key',
  55. 'suffix_key',
  56. 'background_color',
  57. 'text_color',
  58. )
  59. class SpanTypeSerializer(LabelSerializer):
  60. class Meta:
  61. model = SpanType
  62. fields = (
  63. 'id',
  64. 'text',
  65. 'prefix_key',
  66. 'suffix_key',
  67. 'background_color',
  68. 'text_color',
  69. )
  70. class CommentSerializer(serializers.ModelSerializer):
  71. class Meta:
  72. model = Comment
  73. fields = ('id', 'user', 'username', 'example', 'text', 'created_at', )
  74. read_only_fields = ('user', 'example')
  75. class TagSerializer(serializers.ModelSerializer):
  76. class Meta:
  77. model = Tag
  78. fields = ('id', 'project', 'text', )
  79. read_only_fields = ('id', 'project')
  80. class ExampleSerializer(serializers.ModelSerializer):
  81. annotation_approver = serializers.SerializerMethodField()
  82. is_confirmed = serializers.SerializerMethodField()
  83. @classmethod
  84. def get_annotation_approver(cls, instance):
  85. approver = instance.annotations_approved_by
  86. return approver.username if approver else None
  87. def get_is_confirmed(self, instance):
  88. user = self.context.get('request').user
  89. if instance.project.collaborative_annotation:
  90. states = instance.states.all()
  91. else:
  92. states = instance.states.filter(confirmed_by_id=user.id)
  93. return states.count() > 0
  94. class Meta:
  95. model = Example
  96. fields = [
  97. 'id',
  98. 'filename',
  99. 'meta',
  100. 'annotation_approver',
  101. 'comment_count',
  102. 'text',
  103. 'is_confirmed'
  104. ]
  105. read_only_fields = ['filename', 'is_confirmed']
  106. class ExampleStateSerializer(serializers.ModelSerializer):
  107. class Meta:
  108. model = ExampleState
  109. fields = ('id', 'example', 'confirmed_by')
  110. read_only_fields = ('id', 'example', 'confirmed_by')
  111. class ApproverSerializer(ExampleSerializer):
  112. class Meta:
  113. model = Example
  114. fields = ('id', 'annotation_approver')
  115. class ProjectSerializer(serializers.ModelSerializer):
  116. tags = TagSerializer(many=True, required=False)
  117. class Meta:
  118. model = Project
  119. fields = (
  120. 'id',
  121. 'name',
  122. 'description',
  123. 'guideline',
  124. 'project_type',
  125. 'updated_at',
  126. 'random_order',
  127. 'created_by',
  128. 'collaborative_annotation',
  129. 'single_class_classification',
  130. 'is_text_project',
  131. 'can_define_label',
  132. 'can_define_relation',
  133. 'can_define_category',
  134. 'can_define_span',
  135. 'tags'
  136. )
  137. read_only_fields = (
  138. 'updated_at',
  139. 'is_text_project',
  140. 'can_define_label',
  141. 'can_define_relation',
  142. 'can_define_category',
  143. 'can_define_span',
  144. 'tags'
  145. )
  146. class TextClassificationProjectSerializer(ProjectSerializer):
  147. class Meta(ProjectSerializer.Meta):
  148. model = TextClassificationProject
  149. class SequenceLabelingProjectSerializer(ProjectSerializer):
  150. class Meta(ProjectSerializer.Meta):
  151. model = SequenceLabelingProject
  152. fields = ProjectSerializer.Meta.fields + ('allow_overlapping', 'grapheme_mode')
  153. class Seq2seqProjectSerializer(ProjectSerializer):
  154. class Meta(ProjectSerializer.Meta):
  155. model = Seq2seqProject
  156. class IntentDetectionAndSlotFillingProjectSerializer(ProjectSerializer):
  157. class Meta(ProjectSerializer.Meta):
  158. model = IntentDetectionAndSlotFillingProject
  159. class Speech2textProjectSerializer(ProjectSerializer):
  160. class Meta(ProjectSerializer.Meta):
  161. model = Speech2textProject
  162. class ImageClassificationProjectSerializer(ProjectSerializer):
  163. class Meta(ProjectSerializer.Meta):
  164. model = ImageClassificationProject
  165. class ProjectPolymorphicSerializer(PolymorphicSerializer):
  166. model_serializer_mapping = {
  167. Project: ProjectSerializer,
  168. **{
  169. cls.Meta.model: cls for cls in ProjectSerializer.__subclasses__()
  170. }
  171. }
  172. class CategorySerializer(serializers.ModelSerializer):
  173. label = serializers.PrimaryKeyRelatedField(queryset=CategoryType.objects.all())
  174. example = serializers.PrimaryKeyRelatedField(queryset=Example.objects.all())
  175. class Meta:
  176. model = Category
  177. fields = (
  178. 'id',
  179. 'prob',
  180. 'user',
  181. 'example',
  182. 'created_at',
  183. 'updated_at',
  184. 'label',
  185. )
  186. read_only_fields = ('user',)
  187. class SpanSerializer(serializers.ModelSerializer):
  188. label = serializers.PrimaryKeyRelatedField(queryset=SpanType.objects.all())
  189. example = serializers.PrimaryKeyRelatedField(queryset=Example.objects.all())
  190. class Meta:
  191. model = Span
  192. fields = (
  193. 'id',
  194. 'prob',
  195. 'user',
  196. 'example',
  197. 'created_at',
  198. 'updated_at',
  199. 'label',
  200. 'start_offset',
  201. 'end_offset',
  202. )
  203. read_only_fields = ('user',)
  204. class TextLabelSerializer(serializers.ModelSerializer):
  205. example = serializers.PrimaryKeyRelatedField(queryset=Example.objects.all())
  206. class Meta:
  207. model = TextLabel
  208. fields = (
  209. 'id',
  210. 'prob',
  211. 'user',
  212. 'example',
  213. 'created_at',
  214. 'updated_at',
  215. 'text',
  216. )
  217. read_only_fields = ('user',)
  218. class RelationTypesSerializer(serializers.ModelSerializer):
  219. def validate(self, attrs):
  220. return super().validate(attrs)
  221. class Meta:
  222. model = RelationTypes
  223. fields = ('id', 'color', 'name')
  224. class AnnotationRelationsSerializer(serializers.ModelSerializer):
  225. def validate(self, attrs):
  226. return super().validate(attrs)
  227. class Meta:
  228. model = AnnotationRelations
  229. fields = ('id', 'annotation_id_1', 'annotation_id_2', 'type', 'user', 'timestamp')