|
2 | 2 | """ |
3 | 3 | import logging |
4 | 4 |
|
5 | | -from django.db.models import signals |
6 | 5 | from datetime import datetime |
| 6 | +from django.db.models.signals import post_delete, pre_delete |
7 | 7 |
|
8 | 8 | from core.permissions import AllPermissions |
9 | 9 | from core.redis import start_job_async_or_sync |
10 | | -from core.utils.common import temporary_disconnect_signal, temporary_disconnect_all_signals |
| 10 | +from core.utils.common import temporary_disconnect_list_signal |
| 11 | +from projects.models import Project |
| 12 | + |
11 | 13 | from tasks.models import ( |
12 | | - Annotation, Prediction, Task, update_is_labeled_after_removing_annotation, |
13 | | - bulk_update_stats_project_tasks |
| 14 | + Annotation, Prediction, Task, bulk_update_stats_project_tasks, update_is_labeled_after_removing_annotation, |
| 15 | + update_all_task_states_after_deleting_task, remove_data_columns, remove_project_summary_annotations |
14 | 16 | ) |
15 | 17 | from webhooks.utils import emit_webhooks_for_instance |
16 | 18 | from webhooks.models import WebhookAction |
@@ -38,25 +40,36 @@ def delete_tasks(project, queryset, **kwargs): |
38 | 40 | """ |
39 | 41 | tasks_ids = list(queryset.values('id')) |
40 | 42 | count = len(tasks_ids) |
| 43 | + tasks_ids_list = [task['id'] for task in tasks_ids] |
| 44 | + # signals to switch off |
| 45 | + signals = [ |
| 46 | + (post_delete, update_is_labeled_after_removing_annotation, Annotation), |
| 47 | + (post_delete, update_all_task_states_after_deleting_task, Task), |
| 48 | + (pre_delete, remove_data_columns, Task), |
| 49 | + (pre_delete, remove_project_summary_annotations, Annotation) |
| 50 | + ] |
41 | 51 |
|
42 | 52 | # delete all project tasks |
43 | 53 | if count == project.tasks.count(): |
44 | | - with temporary_disconnect_all_signals(): |
| 54 | + with temporary_disconnect_list_signal(signals): |
45 | 55 | queryset.delete() |
46 | | - |
47 | 56 | project.summary.reset() |
48 | | - project.update_tasks_states( |
49 | | - maximum_annotations_changed=False, |
50 | | - overlap_cohort_percentage_changed=False, |
51 | | - tasks_number_changed=True |
52 | | - ) |
53 | 57 |
|
54 | 58 | # delete only specific tasks |
55 | 59 | else: |
56 | | - # this signal re-save the task back |
57 | | - with temporary_disconnect_signal(signals.post_delete, update_is_labeled_after_removing_annotation, Annotation): |
| 60 | + # update project summary |
| 61 | + start_job_async_or_sync(async_project_summary_recalculation, tasks_ids_list, project.id) |
| 62 | + |
| 63 | + with temporary_disconnect_list_signal(signals): |
58 | 64 | queryset.delete() |
59 | 65 |
|
| 66 | + project.update_tasks_states( |
| 67 | + maximum_annotations_changed=False, |
| 68 | + overlap_cohort_percentage_changed=False, |
| 69 | + tasks_number_changed=True |
| 70 | + ) |
| 71 | + |
| 72 | + # emit webhooks for project |
60 | 73 | emit_webhooks_for_instance(project.organization, project, WebhookAction.TASKS_DELETED, tasks_ids) |
61 | 74 |
|
62 | 75 | # remove all tabs if there are no tasks in project |
@@ -103,6 +116,13 @@ def delete_tasks_predictions(project, queryset, **kwargs): |
103 | 116 | return {'processed_items': count, 'detail': 'Deleted ' + str(count) + ' predictions'} |
104 | 117 |
|
105 | 118 |
|
| 119 | +def async_project_summary_recalculation(tasks_ids_list, project_id): |
| 120 | + queryset = Task.objects.filter(id__in=tasks_ids_list) |
| 121 | + project = Project.objects.get(id=project_id) |
| 122 | + project.summary.remove_created_annotations_and_labels(Annotation.objects.filter(task__in=queryset)) |
| 123 | + project.summary.remove_data_columns(queryset) |
| 124 | + |
| 125 | + |
106 | 126 | actions = [ |
107 | 127 | { |
108 | 128 | 'entry_point': retrieve_tasks_predictions, |
|
0 commit comments