From 0a3a33aac5472d86cd5f629dfabc89c3d5f2dd86 Mon Sep 17 00:00:00 2001 From: Anler Hp Date: Mon, 23 Jun 2014 17:25:05 +0200 Subject: [PATCH] Optimizing `Project.update_role_points` method --- taiga/projects/models.py | 24 ++++++++++++-------- taiga/projects/userstories/models.py | 2 +- tests/integration/test_models.py | 33 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 tests/integration/test_models.py diff --git a/taiga/projects/models.py b/taiga/projects/models.py index 613e1b0c..3408bf7a 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -181,12 +181,13 @@ class Project(ProjectDefaults, TaggedMixin, models.Model): members = self.memberships.values_list("user", flat=True) return user_model.objects.filter(id__in=list(members)) - def update_role_points(self): - rolepoints_model = get_model("userstories", "RolePoints") + def update_role_points(self, user_stories=None): + RolePoints = get_model("userstories", "RolePoints") + Role = get_model("users", "Role") # Get all available roles on this project roles = self.get_roles().filter(computable=True) - if len(roles) == 0: + if roles.count() == 0: return # Get point instance that represent a null/undefined @@ -194,14 +195,19 @@ class Project(ProjectDefaults, TaggedMixin, models.Model): # Iter over all project user stories and create # role point instance for new created roles. - for us in self.user_stories.all(): - for role in roles: - if not us.role_points.filter(role=role).exists(): - rolepoints_model.objects.create(role=role, user_story=us, - points=null_points_value) + if user_stories is None: + user_stories = self.user_stories.all() + + for story in user_stories: + story_related_roles = Role.objects.filter(role_points__in=story.role_points.all())\ + .distinct() + new_roles = roles.exclude(id__in=story_related_roles) + new_rolepoints = [RolePoints(role=role, user_story=story, points=null_points_value) + for role in new_roles] + RolePoints.objects.bulk_create(new_rolepoints) # Now remove rolepoints associated with not existing roles. - rp_query = rolepoints_model.objects.filter(user_story__in=self.user_stories.all()) + rp_query = RolePoints.objects.filter(user_story__in=self.user_stories.all()) rp_query = rp_query.exclude(role__id__in=roles.values_list("id", flat=True)) rp_query.delete() diff --git a/taiga/projects/userstories/models.py b/taiga/projects/userstories/models.py index 3d9a2cf5..ad99935f 100644 --- a/taiga/projects/userstories/models.py +++ b/taiga/projects/userstories/models.py @@ -141,7 +141,7 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod @receiver(models.signals.post_save, sender=UserStory, dispatch_uid="user_story_create_role_points_handler") def us_create_role_points_handler(sender, instance, **kwargs): - instance.project.update_role_points() + instance.project.update_role_points(user_stories=[instance]) @receiver(models.signals.post_save, sender=UserStory, diff --git a/tests/integration/test_models.py b/tests/integration/test_models.py new file mode 100644 index 00000000..5b6547b8 --- /dev/null +++ b/tests/integration/test_models.py @@ -0,0 +1,33 @@ +import pytest + +from .. import factories as f +from ..utils import disconnect_signals, reconnect_signals + + +def setup_module(): + disconnect_signals() + + +def teardown_module(): + reconnect_signals() + + +pytestmark = pytest.mark.django_db + + +def test_project_update_role_points(): + """Test that relation to project roles are created for stories not related to those roles. + + The "relation" is just a mere `RolePoints` relation between the story and the role with + points set to the project's null-point. + """ + project = f.ProjectFactory.create() + related_role = f.RoleFactory.create(project=project, computable=True) + not_related_role = f.RoleFactory.create(project=project, computable=True) + null_points = f.PointsFactory.create(project=project, value=None) + user_story = f.UserStoryFactory(project=project) + user_story.role_points.add(f.RolePointsFactory(role=related_role, points=null_points)) + + project.update_role_points() + + assert user_story.role_points.filter(role=not_related_role, points=null_points).count() == 1