Browse Source

Add CategoryManager

pull/1650/head
Hironsan 2 years ago
parent
commit
9384f1c96a
3 changed files with 156 additions and 1 deletions
  1. 20
      backend/api/managers.py
  2. 4
      backend/api/models.py
  3. 133
      backend/api/tests/test_category.py

20
backend/api/managers.py

@ -29,6 +29,26 @@ class AnnotationManager(Manager):
distribution[username][label] = count distribution[username][label] = count
return distribution return distribution
def can_annotate(self, label, project) -> bool:
raise NotImplementedError('Please implement this method in the subclass')
class CategoryManager(AnnotationManager):
def get_labels(self, label, project):
if project.collaborative_annotation:
return self.filter(example=label.example)
else:
return self.filter(example=label.example, user=label.user)
def can_annotate(self, label, project) -> bool:
is_exclusive = project.single_class_classification
categories = self.get_labels(label, project)
if is_exclusive:
return not categories.exists()
else:
return not categories.filter(label=label.label).exists()
class ExampleManager(Manager): class ExampleManager(Manager):

4
backend/api/models.py

@ -8,7 +8,8 @@ from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
from .managers import AnnotationManager, ExampleManager, ExampleStateManager
from .managers import (AnnotationManager, CategoryManager, ExampleManager,
ExampleStateManager)
DOCUMENT_CLASSIFICATION = 'DocumentClassification' DOCUMENT_CLASSIFICATION = 'DocumentClassification'
SEQUENCE_LABELING = 'SequenceLabeling' SEQUENCE_LABELING = 'SequenceLabeling'
@ -334,6 +335,7 @@ class Annotation(models.Model):
class Category(Annotation): class Category(Annotation):
objects = CategoryManager()
example = models.ForeignKey( example = models.ForeignKey(
to=Example, to=Example,
on_delete=models.CASCADE, on_delete=models.CASCADE,

133
backend/api/tests/test_category.py

@ -0,0 +1,133 @@
import abc
from django.test import TestCase
from model_mommy import mommy
from api.models import DOCUMENT_CLASSIFICATION, Category
from .api.utils import prepare_project
class TestCategoryAnnotation(abc.ABC, TestCase):
exclusive = True
collaborative = False
@classmethod
def setUpTestData(cls):
cls.project = prepare_project(
DOCUMENT_CLASSIFICATION,
single_class_classification=cls.exclusive,
collaborative_annotation=cls.collaborative
)
cls.example = mommy.make('Example', project=cls.project.item)
cls.label_type = mommy.make('CategoryType', project=cls.project.item)
users = cls.project.users
cls.user = users[0]
cls.another_user = users[1]
cls.category = Category(
example=cls.example,
label=cls.label_type,
user=cls.user
)
def test_can_annotate_category_to_unannotated_data(self):
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertTrue(can_annotate)
class TestExclusiveCategoryAnnotation(TestCategoryAnnotation):
exclusive = True
collaborative = False
def test_cannot_annotate_different_category_to_annotated_data(self):
mommy.make('Category', example=self.example, user=self.user)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
def test_cannot_annotate_same_category_to_annotated_data(self):
mommy.make('Category', example=self.example, label=self.label_type, user=self.user)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
def test_allow_another_user_to_annotate_same_category(self):
mommy.make(
'Category',
example=self.example,
label=self.label_type,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertTrue(can_annotate)
class TestNonExclusiveCategoryAnnotation(TestCategoryAnnotation):
exclusive = False
collaborative = False
def test_can_annotate_different_category_to_annotated_data(self):
mommy.make('Category', example=self.example, user=self.user)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertTrue(can_annotate)
def test_cannot_annotate_same_category_to_annotated_data(self):
mommy.make('Category', example=self.example, label=self.label_type, user=self.user)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
def test_allow_another_user_to_annotate_same_category(self):
mommy.make(
'Category',
example=self.example,
label=self.label_type,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertTrue(can_annotate)
class TestCollaborativeExclusiveCategoryAnnotation(TestCategoryAnnotation):
exclusive = True
collaborative = True
def test_deny_another_user_to_annotate_same_category(self):
mommy.make(
'Category',
example=self.example,
label=self.label_type,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
def test_deny_another_user_to_annotate_different_category(self):
mommy.make(
'Category',
example=self.example,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
class TestCollaborativeNonExclusiveCategoryAnnotation(TestCategoryAnnotation):
exclusive = False
collaborative = True
def test_deny_another_user_to_annotate_same_category(self):
mommy.make(
'Category',
example=self.example,
label=self.label_type,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertFalse(can_annotate)
def test_allow_another_user_to_annotate_different_category(self):
mommy.make(
'Category',
example=self.example,
user=self.another_user
)
can_annotate = Category.objects.can_annotate(self.category, self.project.item)
self.assertTrue(can_annotate)
Loading…
Cancel
Save