Repository: doccano/doccano

Issue:
Cannot use the same shortcut and label name in different projects
The issue is the following:

1. I create Project A.
2. Import some annotated data to the project - set of labels is automatically created as a result (let's say, Label 1, Label 2, Label 3)
3. I edit these labels - provide a shortcut and color
4. I create Project B and import another portion of dataset (with the same set of labels)
5. I try to replicate setting of Project A (assign the same shortcuts, colors and label names to labels), which gives me an error:
`You cannot use same label name or shortcut key.`

It seems not very convenient that we cannot create labels with the same shortcut and label name in different project. I wonder if it was made intentionally or it is a bug.

Thank you very much for a great tool.


Discussion:
Thanks! I will check the problem.

Resolving patch:
diff --git a/app/server/serializers.py b/app/server/serializers.py
--- a/app/server/serializers.py
+++ b/app/server/serializers.py
@@ -34,8 +34,11 @@ def validate(self, attrs):
             raise ValidationError('Shortcut key may not have a suffix key.')
 
         # Don't allow to save same shortcut key when prefix_key is null.
+        context = self.context['request'].parser_context
+        project_id = context['kwargs'].get('project_id')
         if Label.objects.filter(suffix_key=suffix_key,
-                                prefix_key__isnull=True).exists():
+                                prefix_key__isnull=True,
+                                project=project_id).exists():
             raise ValidationError('Duplicate key.')
         return super().validate(attrs)
 


Test patch:
diff --git a/app/server/tests/test_api.py b/app/server/tests/test_api.py
--- a/app/server/tests/test_api.py
+++ b/app/server/tests/test_api.py
@@ -152,8 +152,10 @@ def setUpTestData(cls):
         cls.main_project_label = mommy.make('server.Label', project=cls.main_project)
 
         sub_project = mommy.make('server.Project', users=[non_project_member])
+        other_project = mommy.make('server.Project', users=[super_user])
         mommy.make('server.Label', project=sub_project)
         cls.url = reverse(viewname='label_list', args=[cls.main_project.id])
+        cls.other_url = reverse(viewname='label_list', args=[other_project.id])
         cls.data = {'text': 'example'}
 
     def test_returns_labels_to_project_member(self):
@@ -194,6 +196,15 @@ def test_can_create_multiple_labels_without_shortcut_key(self):
             response = self.client.post(self.url, format='json', data=label)
             self.assertEqual(response.status_code, status.HTTP_201_CREATED)
 
+    def test_can_create_same_label_in_multiple_projects(self):
+        self.client.login(username=self.super_user_name,
+                          password=self.super_user_pass)
+        label = {'text': 'LOC', 'prefix_key': None, 'suffix_key': 'l'}
+        response = self.client.post(self.url, format='json', data=label)
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+        response = self.client.post(self.other_url, format='json', data=label)
+        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+
     def test_disallows_project_member_to_create_label(self):
         self.client.login(username=self.project_member_name,
                           password=self.project_member_pass)