From 7b180e325acd63adbb9bedd033a7f8743b104566 Mon Sep 17 00:00:00 2001 From: Hironsan Date: Fri, 28 Jan 2022 11:30:01 +0900 Subject: [PATCH] Move code related to example to example app --- backend/api/permissions.py | 9 ---- backend/api/serializers.py | 50 +------------------ backend/api/urls.py | 27 +--------- backend/app/settings.py | 1 + backend/app/urls.py | 1 + backend/examples/__init__.py | 0 backend/examples/admin.py | 0 backend/examples/apps.py | 6 +++ backend/{api => examples}/filters.py | 2 +- backend/examples/migrations/__init__.py | 0 backend/examples/models.py | 0 backend/examples/permissions.py | 10 ++++ backend/examples/serializers.py | 50 +++++++++++++++++++ backend/examples/tests/__init__.py | 0 .../api => examples/tests}/test_comment.py | 3 +- .../api => examples/tests}/test_document.py | 5 +- .../tests}/test_example_state.py | 3 +- .../{api => examples}/tests/test_filters.py | 5 +- .../{api => examples}/tests/test_models.py | 3 +- backend/examples/urls.py | 34 +++++++++++++ backend/examples/views/__init__.py | 0 backend/{api => examples}/views/comment.py | 7 ++- backend/{api => examples}/views/example.py | 7 ++- .../{api => examples}/views/example_state.py | 5 +- 24 files changed, 120 insertions(+), 108 deletions(-) create mode 100644 backend/examples/__init__.py create mode 100644 backend/examples/admin.py create mode 100644 backend/examples/apps.py rename backend/{api => examples}/filters.py (96%) create mode 100644 backend/examples/migrations/__init__.py create mode 100644 backend/examples/models.py create mode 100644 backend/examples/permissions.py create mode 100644 backend/examples/serializers.py create mode 100644 backend/examples/tests/__init__.py rename backend/{api/tests/api => examples/tests}/test_comment.py (98%) rename backend/{api/tests/api => examples/tests}/test_document.py (97%) rename backend/{api/tests/api => examples/tests}/test_example_state.py (96%) rename backend/{api => examples}/tests/test_filters.py (95%) rename backend/{api => examples}/tests/test_models.py (98%) create mode 100644 backend/examples/urls.py create mode 100644 backend/examples/views/__init__.py rename backend/{api => examples}/views/comment.py (91%) rename backend/{api => examples}/views/example.py (93%) rename backend/{api => examples}/views/example_state.py (90%) diff --git a/backend/api/permissions.py b/backend/api/permissions.py index e2d6596b..456c4fe9 100644 --- a/backend/api/permissions.py +++ b/backend/api/permissions.py @@ -1,15 +1,6 @@ from rest_framework.permissions import BasePermission -class IsOwnComment(BasePermission): - @classmethod - def has_object_permission(cls, request, view, obj): - if request.user.is_superuser: - return True - - return obj.user.id == request.user.id - - class IsStaff(BasePermission): def has_permission(self, request, view): if request.user.is_superuser or request.user.is_staff: diff --git a/backend/api/serializers.py b/backend/api/serializers.py index 7bfc890e..7e112b85 100644 --- a/backend/api/serializers.py +++ b/backend/api/serializers.py @@ -1,21 +1,12 @@ from rest_framework import serializers from rest_polymorphic.serializers import PolymorphicSerializer -from .models import (Comment, Example, ExampleState, - ImageClassificationProject, +from .models import (ImageClassificationProject, IntentDetectionAndSlotFillingProject, Project, Seq2seqProject, SequenceLabelingProject, Speech2textProject, Tag, TextClassificationProject) -class CommentSerializer(serializers.ModelSerializer): - - class Meta: - model = Comment - fields = ('id', 'user', 'username', 'example', 'text', 'created_at', ) - read_only_fields = ('user', 'example') - - class TagSerializer(serializers.ModelSerializer): class Meta: @@ -24,45 +15,6 @@ class TagSerializer(serializers.ModelSerializer): read_only_fields = ('id', 'project') -class ExampleSerializer(serializers.ModelSerializer): - annotation_approver = serializers.SerializerMethodField() - is_confirmed = serializers.SerializerMethodField() - - @classmethod - def get_annotation_approver(cls, instance): - approver = instance.annotations_approved_by - return approver.username if approver else None - - def get_is_confirmed(self, instance): - user = self.context.get('request').user - if instance.project.collaborative_annotation: - states = instance.states.all() - else: - states = instance.states.filter(confirmed_by_id=user.id) - return states.count() > 0 - - class Meta: - model = Example - fields = [ - 'id', - 'filename', - 'meta', - 'annotation_approver', - 'comment_count', - 'text', - 'is_confirmed' - ] - read_only_fields = ['filename', 'is_confirmed'] - - -class ExampleStateSerializer(serializers.ModelSerializer): - - class Meta: - model = ExampleState - fields = ('id', 'example', 'confirmed_by') - read_only_fields = ('id', 'example', 'confirmed_by') - - class ProjectSerializer(serializers.ModelSerializer): tags = TagSerializer(many=True, required=False) diff --git a/backend/api/urls.py b/backend/api/urls.py index 3115be8b..7370c4e7 100644 --- a/backend/api/urls.py +++ b/backend/api/urls.py @@ -1,18 +1,8 @@ from django.urls import include, path -from .views import comment, example, example_state, health, project, tag, task +from .views import health, project, tag, task urlpatterns_project = [ - path( - route='examples', - view=example.ExampleList.as_view(), - name='example_list' - ), - path( - route='examples/', - view=example.ExampleDetail.as_view(), - name='example_detail' - ), path( route='tags', view=tag.TagList.as_view(), @@ -23,21 +13,6 @@ urlpatterns_project = [ view=tag.TagDetail.as_view(), name='tag_detail' ), - path( - route='comments', - view=comment.CommentList.as_view(), - name='comment_list' - ), - path( - route='comments/', - view=comment.CommentDetail.as_view(), - name='comment_detail' - ), - path( - route='examples//states', - view=example_state.ExampleStateList.as_view(), - name='example_state_list' - ), ] urlpatterns = [ diff --git a/backend/app/settings.py b/backend/app/settings.py index adf1fb59..981519a0 100644 --- a/backend/app/settings.py +++ b/backend/app/settings.py @@ -61,6 +61,7 @@ INSTALLED_APPS = [ 'auto_labeling.apps.AutoLabelingConfig', 'labels.apps.LabelsConfig', 'label_types.apps.LabelTypesConfig', + 'examples.apps.ExamplesConfig', 'rest_framework', 'rest_framework.authtoken', 'django_filters', diff --git a/backend/app/urls.py b/backend/app/urls.py index 1c7964d1..c5fb3fd3 100644 --- a/backend/app/urls.py +++ b/backend/app/urls.py @@ -48,6 +48,7 @@ urlpatterns += [ path('v1/projects//', include('members.urls')), path('v1/projects//metrics/', include('metrics.urls')), path('v1/projects//', include('auto_labeling.urls')), + path('v1/projects//', include('examples.urls')), path('v1/projects//', include('labels.urls')), path('v1/projects//', include('label_types.urls')), path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), diff --git a/backend/examples/__init__.py b/backend/examples/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/examples/admin.py b/backend/examples/admin.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/examples/apps.py b/backend/examples/apps.py new file mode 100644 index 00000000..d6f5703a --- /dev/null +++ b/backend/examples/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ExamplesConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'examples' diff --git a/backend/api/filters.py b/backend/examples/filters.py similarity index 96% rename from backend/api/filters.py rename to backend/examples/filters.py index e035fc65..3fd1954d 100644 --- a/backend/api/filters.py +++ b/backend/examples/filters.py @@ -1,7 +1,7 @@ from django.db.models import Count, Q from django_filters.rest_framework import BooleanFilter, FilterSet -from .models import Example +from api.models import Example class ExampleFilter(FilterSet): diff --git a/backend/examples/migrations/__init__.py b/backend/examples/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/examples/models.py b/backend/examples/models.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/examples/permissions.py b/backend/examples/permissions.py new file mode 100644 index 00000000..258a1654 --- /dev/null +++ b/backend/examples/permissions.py @@ -0,0 +1,10 @@ +from rest_framework.permissions import BasePermission + + +class IsOwnComment(BasePermission): + @classmethod + def has_object_permission(cls, request, view, obj): + if request.user.is_superuser: + return True + + return obj.user.id == request.user.id diff --git a/backend/examples/serializers.py b/backend/examples/serializers.py new file mode 100644 index 00000000..de009000 --- /dev/null +++ b/backend/examples/serializers.py @@ -0,0 +1,50 @@ +from rest_framework import serializers + +from api.models import Comment, Example, ExampleState + + +class CommentSerializer(serializers.ModelSerializer): + + class Meta: + model = Comment + fields = ('id', 'user', 'username', 'example', 'text', 'created_at', ) + read_only_fields = ('user', 'example') + + +class ExampleSerializer(serializers.ModelSerializer): + annotation_approver = serializers.SerializerMethodField() + is_confirmed = serializers.SerializerMethodField() + + @classmethod + def get_annotation_approver(cls, instance): + approver = instance.annotations_approved_by + return approver.username if approver else None + + def get_is_confirmed(self, instance): + user = self.context.get('request').user + if instance.project.collaborative_annotation: + states = instance.states.all() + else: + states = instance.states.filter(confirmed_by_id=user.id) + return states.count() > 0 + + class Meta: + model = Example + fields = [ + 'id', + 'filename', + 'meta', + 'annotation_approver', + 'comment_count', + 'text', + 'is_confirmed' + ] + read_only_fields = ['filename', 'is_confirmed'] + + +class ExampleStateSerializer(serializers.ModelSerializer): + + class Meta: + model = ExampleState + fields = ('id', 'example', 'confirmed_by') + read_only_fields = ('id', 'example', 'confirmed_by') diff --git a/backend/examples/tests/__init__.py b/backend/examples/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/api/tests/api/test_comment.py b/backend/examples/tests/test_comment.py similarity index 98% rename from backend/api/tests/api/test_comment.py rename to backend/examples/tests/test_comment.py index aca84d3f..b0abc46e 100644 --- a/backend/api/tests/api/test_comment.py +++ b/backend/examples/tests/test_comment.py @@ -1,8 +1,7 @@ from rest_framework import status from rest_framework.reverse import reverse -from .utils import (CRUDMixin, make_comment, make_doc, make_user, - prepare_project) +from api.tests.api.utils import (CRUDMixin, make_comment, make_doc, make_user, prepare_project) class TestCommentListDocAPI(CRUDMixin): diff --git a/backend/api/tests/api/test_document.py b/backend/examples/tests/test_document.py similarity index 97% rename from backend/api/tests/api/test_document.py rename to backend/examples/tests/test_document.py index 86384f48..d0f068f8 100644 --- a/backend/api/tests/api/test_document.py +++ b/backend/examples/tests/test_document.py @@ -4,9 +4,8 @@ from rest_framework import status from rest_framework.reverse import reverse from api.models import DOCUMENT_CLASSIFICATION - -from .utils import (CRUDMixin, assign_user_to_role, make_doc, - make_example_state, make_user, prepare_project) +from api.tests.api.utils import (CRUDMixin, assign_user_to_role, make_doc, + make_example_state, make_user, prepare_project) class TestExampleListAPI(CRUDMixin): diff --git a/backend/api/tests/api/test_example_state.py b/backend/examples/tests/test_example_state.py similarity index 96% rename from backend/api/tests/api/test_example_state.py rename to backend/examples/tests/test_example_state.py index 42b1b1cd..f659969f 100644 --- a/backend/api/tests/api/test_example_state.py +++ b/backend/examples/tests/test_example_state.py @@ -1,8 +1,7 @@ from rest_framework import status from rest_framework.reverse import reverse -from .utils import (CRUDMixin, make_doc, make_example_state, make_user, - prepare_project) +from api.tests.api.utils import (CRUDMixin, make_doc, make_example_state, make_user, prepare_project) class TestExampleStateList(CRUDMixin): diff --git a/backend/api/tests/test_filters.py b/backend/examples/tests/test_filters.py similarity index 95% rename from backend/api/tests/test_filters.py rename to backend/examples/tests/test_filters.py index 30b2d7d4..000cc8c5 100644 --- a/backend/api/tests/test_filters.py +++ b/backend/examples/tests/test_filters.py @@ -2,10 +2,9 @@ from unittest.mock import MagicMock from django.test import TestCase -from api.filters import ExampleFilter from api.models import Example - -from .api.utils import make_doc, make_example_state, prepare_project +from api.tests.api.utils import make_doc, make_example_state, prepare_project +from examples.filters import ExampleFilter class TestFilterMixin(TestCase): diff --git a/backend/api/tests/test_models.py b/backend/examples/tests/test_models.py similarity index 98% rename from backend/api/tests/test_models.py rename to backend/examples/tests/test_models.py index 8d1bf38f..596598fd 100644 --- a/backend/api/tests/test_models.py +++ b/backend/examples/tests/test_models.py @@ -2,8 +2,7 @@ from django.test import TestCase from model_mommy import mommy from api.models import IMAGE_CLASSIFICATION, SEQUENCE_LABELING, ExampleState - -from .api.utils import prepare_project +from api.tests.api.utils import prepare_project class TestExampleState(TestCase): diff --git a/backend/examples/urls.py b/backend/examples/urls.py new file mode 100644 index 00000000..9c22ac3f --- /dev/null +++ b/backend/examples/urls.py @@ -0,0 +1,34 @@ +from django.urls import path + +from .views.example import ExampleList, ExampleDetail +from .views.comment import CommentList, CommentDetail +from .views.example_state import ExampleStateList + + +urlpatterns = [ + path( + route='examples', + view=ExampleList.as_view(), + name='example_list' + ), + path( + route='examples/', + view=ExampleDetail.as_view(), + name='example_detail' + ), + path( + route='comments', + view=CommentList.as_view(), + name='comment_list' + ), + path( + route='comments/', + view=CommentDetail.as_view(), + name='comment_detail' + ), + path( + route='examples//states', + view=ExampleStateList.as_view(), + name='example_state_list' + ), +] diff --git a/backend/examples/views/__init__.py b/backend/examples/views/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/api/views/comment.py b/backend/examples/views/comment.py similarity index 91% rename from backend/api/views/comment.py rename to backend/examples/views/comment.py index 727637e4..c4800b1e 100644 --- a/backend/api/views/comment.py +++ b/backend/examples/views/comment.py @@ -3,11 +3,10 @@ from rest_framework import filters, generics, status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from api.models import Comment from members.permissions import IsInProjectOrAdmin - -from ..models import Comment -from ..permissions import IsOwnComment -from ..serializers import CommentSerializer +from examples.permissions import IsOwnComment +from examples.serializers import CommentSerializer class CommentList(generics.ListCreateAPIView): diff --git a/backend/api/views/example.py b/backend/examples/views/example.py similarity index 93% rename from backend/api/views/example.py rename to backend/examples/views/example.py index 54c4c669..6fd67b7e 100644 --- a/backend/api/views/example.py +++ b/backend/examples/views/example.py @@ -7,12 +7,11 @@ from rest_framework import filters, generics, status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from api.models import Example, Project +from examples.filters import ExampleFilter +from examples.serializers import ExampleSerializer from members.permissions import IsInProjectReadOnlyOrAdmin -from ..filters import ExampleFilter -from ..models import Example, Project -from ..serializers import ExampleSerializer - class ExampleList(generics.ListCreateAPIView): serializer_class = ExampleSerializer diff --git a/backend/api/views/example_state.py b/backend/examples/views/example_state.py similarity index 90% rename from backend/api/views/example_state.py rename to backend/examples/views/example_state.py index 7dd232bb..963572f8 100644 --- a/backend/api/views/example_state.py +++ b/backend/examples/views/example_state.py @@ -2,11 +2,10 @@ from django.shortcuts import get_object_or_404 from rest_framework import generics from rest_framework.permissions import IsAuthenticated +from api.models import Example, ExampleState, Project +from examples.serializers import ExampleStateSerializer from members.permissions import IsInProjectOrAdmin -from ..models import Example, ExampleState, Project -from ..serializers import ExampleStateSerializer - class ExampleStateList(generics.ListCreateAPIView): serializer_class = ExampleStateSerializer