diff --git a/taiga/base/utils/db.py b/taiga/base/utils/db.py index b937cf5a..3ef8ba6e 100644 --- a/taiga/base/utils/db.py +++ b/taiga/base/utils/db.py @@ -43,7 +43,7 @@ def reload_attribute(model_instance, attr_name): @transaction.atomic -def save_in_bulk(instances, callback=None, **save_options): +def save_in_bulk(instances, callback=None, precall=None, **save_options): """Save a list of model instances. :params instances: List of model instances. @@ -53,16 +53,20 @@ def save_in_bulk(instances, callback=None, **save_options): if callback is None: callback = functions.identity + if precall is None: + precall = functions.identity + for instance in instances: if instance.pk is None: created = True + precall(instance) instance.save(**save_options) callback(instance, created=True) @transaction.atomic -def update_in_bulk(instances, list_of_new_values, callback=None): +def update_in_bulk(instances, list_of_new_values, callback=None, precall=None): """Update a list of model instances. :params instances: List of model instances. @@ -71,10 +75,13 @@ def update_in_bulk(instances, list_of_new_values, callback=None): """ if callback is None: callback = functions.identity + if precall is None: + precall = functions.identity for instance, new_values in zip(instances, list_of_new_values): for attribute, value in new_values.items(): setattr(instance, attribute, value) + precall(instance) instance.save() callback(instance) diff --git a/taiga/projects/api.py b/taiga/projects/api.py index 04122b86..9b623739 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -188,7 +188,8 @@ class MembershipViewSet(ModelCrudViewSet): project = models.Project.objects.get(id=data["project_id"]) self.check_permissions(request, 'bulk_create', project) members = services.create_members_in_bulk( - data["bulk_memberships"], project=project, callback=self.post_save) + data["bulk_memberships"], project=project, callback=self.post_save, + precall=self.pre_save) members_serialized = self.serializer_class(members, many=True) return response.Ok(data=members_serialized.data) diff --git a/taiga/projects/issues/api.py b/taiga/projects/issues/api.py index 28eaad9c..540d60c7 100644 --- a/taiga/projects/issues/api.py +++ b/taiga/projects/issues/api.py @@ -165,7 +165,7 @@ class IssueViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin, data["bulk_issues"], project=project, owner=request.user, status=project.default_issue_status, severity=project.default_severity, priority=project.default_priority, type=project.default_issue_type, - callback=self.post_save) + callback=self.post_save, precall=self.pre_save) issues_serialized = self.serializer_class(issues, many=True) return response.Ok(data=issues_serialized.data) diff --git a/taiga/projects/issues/services.py b/taiga/projects/issues/services.py index 752557b5..ac2f98ce 100644 --- a/taiga/projects/issues/services.py +++ b/taiga/projects/issues/services.py @@ -31,7 +31,7 @@ def get_issues_from_bulk(bulk_data, **additional_fields): for line in text.split_in_lines(bulk_data)] -def create_issues_in_bulk(bulk_data, callback=None, **additional_fields): +def create_issues_in_bulk(bulk_data, callback=None, precall=None, **additional_fields): """Create issues from `bulk_data`. :param bulk_data: List of issues in bulk format. @@ -41,7 +41,7 @@ def create_issues_in_bulk(bulk_data, callback=None, **additional_fields): :return: List of created `Issue` instances. """ issues = get_issues_from_bulk(bulk_data, **additional_fields) - db.save_in_bulk(issues, callback) + db.save_in_bulk(issues, callback, precall) return issues diff --git a/taiga/projects/services/members.py b/taiga/projects/services/members.py index e35635f0..0758cd66 100644 --- a/taiga/projects/services/members.py +++ b/taiga/projects/services/members.py @@ -19,7 +19,7 @@ def get_members_from_bulk(bulk_data, **additional_fields): return members -def create_members_in_bulk(bulk_data, callback=None, **additional_fields): +def create_members_in_bulk(bulk_data, callback=None, precall=None, **additional_fields): """Create members from `bulk_data`. :param bulk_data: List of dicts `{"project_id": <>, "role_id": <>, "email": <>}`. @@ -29,5 +29,5 @@ def create_members_in_bulk(bulk_data, callback=None, **additional_fields): :return: List of created `Member` instances. """ members = get_members_from_bulk(bulk_data, **additional_fields) - db.save_in_bulk(members, callback) + db.save_in_bulk(members, callback, precall) return members diff --git a/taiga/projects/tasks/api.py b/taiga/projects/tasks/api.py index c67cb15f..9e9d1a3f 100644 --- a/taiga/projects/tasks/api.py +++ b/taiga/projects/tasks/api.py @@ -70,7 +70,7 @@ class TaskViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMixin, tasks = services.create_tasks_in_bulk( data["bulk_tasks"], milestone_id=data["sprint_id"], user_story_id=data["us_id"], status_id=data.get("status_id") or project.default_task_status_id, - project=project, owner=request.user, callback=self.post_save) + project=project, owner=request.user, callback=self.post_save, precall=self.pre_save) tasks_serialized = self.serializer_class(tasks, many=True) return response.Ok(tasks_serialized.data) diff --git a/taiga/projects/tasks/services.py b/taiga/projects/tasks/services.py index 0bd55518..6e9e571c 100644 --- a/taiga/projects/tasks/services.py +++ b/taiga/projects/tasks/services.py @@ -31,7 +31,7 @@ def get_tasks_from_bulk(bulk_data, **additional_fields): for line in text.split_in_lines(bulk_data)] -def create_tasks_in_bulk(bulk_data, callback=None, **additional_fields): +def create_tasks_in_bulk(bulk_data, callback=None, precall=None, **additional_fields): """Create tasks from `bulk_data`. :param bulk_data: List of tasks in bulk format. @@ -41,5 +41,5 @@ def create_tasks_in_bulk(bulk_data, callback=None, **additional_fields): :return: List of created `Task` instances. """ tasks = get_tasks_from_bulk(bulk_data, **additional_fields) - db.save_in_bulk(tasks, callback) + db.save_in_bulk(tasks, callback, precall) return tasks diff --git a/taiga/projects/userstories/api.py b/taiga/projects/userstories/api.py index effa0ec5..04f694cc 100644 --- a/taiga/projects/userstories/api.py +++ b/taiga/projects/userstories/api.py @@ -73,7 +73,7 @@ class UserStoryViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMi user_stories = services.create_userstories_in_bulk( data["bulk_stories"], project=project, owner=request.user, status_id=data.get("status_id") or project.default_us_status_id, - callback=self.post_save) + callback=self.post_save, precall=self.pre_save) user_stories_serialized = self.serializer_class(user_stories, many=True) return response.Ok(user_stories_serialized.data) return response.BadRequest(serializer.errors) diff --git a/taiga/projects/userstories/services.py b/taiga/projects/userstories/services.py index 73dfc965..bec9b7aa 100644 --- a/taiga/projects/userstories/services.py +++ b/taiga/projects/userstories/services.py @@ -33,7 +33,7 @@ def get_userstories_from_bulk(bulk_data, **additional_fields): for line in text.split_in_lines(bulk_data)] -def create_userstories_in_bulk(bulk_data, callback=None, **additional_fields): +def create_userstories_in_bulk(bulk_data, callback=None, precall=None, **additional_fields): """Create user stories from `bulk_data`. :param bulk_data: List of user stories in bulk format. @@ -43,7 +43,7 @@ def create_userstories_in_bulk(bulk_data, callback=None, **additional_fields): :return: List of created `Task` instances. """ userstories = get_userstories_from_bulk(bulk_data, **additional_fields) - db.save_in_bulk(userstories, callback) + db.save_in_bulk(userstories, callback, precall) return userstories