Skip to content

Commit 82b3c53

Browse files
authored
feat: DEV-3259: Support updated_by for Annotations (HumanSignal#3244)
* feat: DEV-3259: Support updated_by for Annotations * added tests for annotation updated_by * update updated_by field when updating annotation * fix migrations conflict
1 parent 3234e3d commit 82b3c53

File tree

4 files changed

+42
-0
lines changed

4 files changed

+42
-0
lines changed

label_studio/tasks/api.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ def update(self, request, *args, **kwargs):
269269
# save user history with annotator_id, time & annotation result
270270
annotation_id = self.kwargs['pk']
271271
annotation = get_object_with_check_and_log(request, Annotation, pk=annotation_id)
272+
annotation.updated_by = request.user
273+
annotation.save(update_fields=['updated_by'])
272274

273275
task = annotation.task
274276
if self.request.data.get('ground_truth'):
@@ -384,6 +386,7 @@ def perform_create(self, ser):
384386
# serialize annotation
385387
extra_args.update({
386388
'prediction': prediction_ser,
389+
'updated_by': user
387390
})
388391

389392
if 'was_cancelled' in self.request.GET:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Generated by Django 3.2.16 on 2022-11-18 23:38
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
def set_updated_by(apps, _):
9+
Annotation = apps.get_model('tasks', 'Annotation')
10+
for obj in Annotation.objects.all().iterator():
11+
obj.updated_by = obj.task.updated_by
12+
obj.save()
13+
14+
class Migration(migrations.Migration):
15+
16+
dependencies = [
17+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
18+
('tasks', '0030_auto_20221102_1118'),
19+
]
20+
21+
operations = [
22+
migrations.AddField(
23+
model_name='annotation',
24+
name='updated_by',
25+
field=models.ForeignKey(help_text='Last user who updated this annotation', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='updated_annotations', to=settings.AUTH_USER_MODEL, verbose_name='updated by'),
26+
),
27+
migrations.RunPython(set_updated_by)
28+
]

label_studio/tasks/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,9 @@ class Annotation(AnnotationMixin, models.Model):
362362
help_text='Project ID for this annotation')
363363
completed_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="annotations", on_delete=models.SET_NULL,
364364
null=True, help_text='User ID of the person who created this annotation')
365+
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='updated_annotations',
366+
on_delete=models.SET_NULL, null=True, verbose_name=_('updated by'),
367+
help_text='Last user who updated this annotation')
365368
was_cancelled = models.BooleanField(_('was cancelled'), default=False, help_text='User skipped the task', db_index=True)
366369
ground_truth = models.BooleanField(_('ground_truth'), default=False, help_text='This annotation is a Ground Truth (ground_truth)', db_index=True)
367370
created_at = models.DateTimeField(_('created at'), auto_now_add=True, help_text='Creation time')
@@ -432,6 +435,9 @@ def update_task(self):
432435
self.task.save(update_fields=update_fields)
433436

434437
def save(self, *args, **kwargs):
438+
request = get_current_request()
439+
if request:
440+
self.updated_by = request.user
435441
result = super().save(*args, **kwargs)
436442
self.update_task()
437443
return result

label_studio/tests/test_annotations.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ def test_create_annotation(caplog, any_client, configured_project_min_annotation
4747
# annotator client
4848
if hasattr(any_client, 'annotator') and any_client.annotator is not None:
4949
assert annotation.completed_by.id == any_client.user.id
50+
assert annotation.updated_by.id == any_client.user.id
5051
# business client
5152
else:
5253
assert annotation.completed_by.id == any_client.business.admin.id
54+
assert annotation.updated_by.id == any_client.business.admin.id
5355

5456
if apps.is_installed('businesses'):
5557
assert annotation.task.accuracy == 1.0
@@ -93,6 +95,9 @@ def test_create_annotation_with_ground_truth(caplog, any_client, configured_proj
9395
assert m.called
9496
task = Task.objects.get(id=task.id)
9597
assert task.annotations.count() == 2
98+
annotations = Annotation.objects.filter(task=task)
99+
for a in annotations:
100+
assert a.updated_by.id == any_client.user.id
96101

97102

98103
@pytest.mark.django_db

0 commit comments

Comments
 (0)