diff --git a/app/api/admin.py b/app/api/admin.py index 5c6c532d..53daf51c 100644 --- a/app/api/admin.py +++ b/app/api/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from .models import (Comment, Document, DocumentAnnotation, Label, Project, Role, RoleMapping, Seq2seqAnnotation, Seq2seqProject, - SequenceAnnotation, SequenceLabelingProject, + SequenceAnnotation, SequenceLabelingProject, Tag, TextClassificationProject) @@ -53,6 +53,13 @@ class RoleMappingAdmin(admin.ModelAdmin): ordering = ('user',) search_fields = ('user__username',) + +class TagAdmin(admin.ModelAdmin): + list_display = ('project', 'text', ) + ordering = ('project', 'text', ) + search_fields = ('text',) + + class CommentAdmin(admin.ModelAdmin): list_display = ('user', 'document', 'text', 'created_at', ) ordering = ('user', 'created_at', ) @@ -71,3 +78,4 @@ admin.site.register(Seq2seqProject, ProjectAdmin) admin.site.register(Role, RoleAdmin) admin.site.register(RoleMapping, RoleMappingAdmin) admin.site.register(Comment, CommentAdmin) +admin.site.register(Tag, TagAdmin) diff --git a/app/api/migrations/0009_tag.py b/app/api/migrations/0009_tag.py new file mode 100644 index 00000000..bc41eeed --- /dev/null +++ b/app/api/migrations/0009_tag.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2 on 2021-04-13 16:50 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0008_auto_20210302_1013'), + ] + + operations = [ + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField()), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to='api.project')), + ], + ), + ] diff --git a/app/api/models.py b/app/api/models.py index cb367151..5f004014 100644 --- a/app/api/models.py +++ b/app/api/models.py @@ -230,6 +230,14 @@ class Comment(models.Model): ordering = ('-created_at', ) +class Tag(models.Model): + text = models.TextField() + project = models.ForeignKey(Project, related_name='tags', on_delete=models.CASCADE) + + def __str__(self): + return self.text + + class Annotation(models.Model): objects = AnnotationManager() diff --git a/app/api/serializers.py b/app/api/serializers.py index 4268f4c0..4ef09792 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, Tag, TextClassificationProject) class UserSerializer(serializers.ModelSerializer): @@ -69,6 +69,14 @@ class CommentSerializer(serializers.ModelSerializer): read_only_fields = ('user', 'document') +class TagSerializer(serializers.ModelSerializer): + + class Meta: + model = Tag + fields = ('id', 'project', 'text', ) + read_only_fields = ('id', 'project') + + class DocumentSerializer(serializers.ModelSerializer): annotations = serializers.SerializerMethodField() annotation_approver = serializers.SerializerMethodField() @@ -103,6 +111,7 @@ class ApproverSerializer(DocumentSerializer): class ProjectSerializer(serializers.ModelSerializer): current_users_role = serializers.SerializerMethodField() + tags = TagSerializer(many=True, required=False) def get_current_users_role(self, instance): role_abstractor = { @@ -122,8 +131,8 @@ class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'description', 'guideline', 'users', 'current_users_role', 'project_type', - 'updated_at', 'randomize_document_order', 'collaborative_annotation', 'single_class_classification') - read_only_fields = ('updated_at', 'users', 'current_users_role') + 'updated_at', 'randomize_document_order', 'collaborative_annotation', 'single_class_classification', 'tags') + read_only_fields = ('updated_at', 'users', 'current_users_role', 'tags') class TextClassificationProjectSerializer(ProjectSerializer): diff --git a/app/api/urls.py b/app/api/urls.py index 06edc4ea..2d75ed42 100644 --- a/app/api/urls.py +++ b/app/api/urls.py @@ -48,6 +48,11 @@ urlpatterns_project = [ view=views.AnnotationDetail.as_view(), name='annotation_detail' ), + path( + route='tags', + view=views.TagList.as_view(), + name='tag_list' + ), path( route='docs//comments', view=views.CommentListDoc.as_view(), @@ -113,7 +118,6 @@ urlpatterns_project = [ view=views.AutoLabelingAnnotation.as_view(), name='auto_labeling_annotation' ), - path( route='auto-labeling-template-testing', view=views.AutoLabelingTemplateTest.as_view(), diff --git a/app/api/views/__init__.py b/app/api/views/__init__.py index f33ef2a9..0571b864 100644 --- a/app/api/views/__init__.py +++ b/app/api/views/__init__.py @@ -8,4 +8,5 @@ from .label import * from .project import * from .role import * from .statistics import * -from .user import * +from .tag import * +from .user import * \ No newline at end of file diff --git a/app/api/views/tag.py b/app/api/views/tag.py new file mode 100644 index 00000000..eb86da4e --- /dev/null +++ b/app/api/views/tag.py @@ -0,0 +1,24 @@ +from django.shortcuts import get_object_or_404 +from rest_framework import generics, status +from rest_framework.response import Response + +from ..models import Project, Tag +from ..serializers import TagSerializer + + +class TagList(generics.ListCreateAPIView): + serializer_class = TagSerializer + pagination_class = None + + def get_queryset(self): + project = get_object_or_404(Project, pk=self.kwargs['project_id']) + return project.tags + + 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_id = request.data['id'] + Tag.objects.get(id=delete_id).delete() + return Response(status=status.HTTP_204_NO_CONTENT)