Some extra api optimizations

remotes/origin/enhancement/email-actions
Alejandro Alonso 2014-12-22 10:02:31 +01:00 committed by David Barragán Merino
parent 99691372a5
commit ca09cda87c
6 changed files with 85 additions and 43 deletions

View File

@ -47,7 +47,12 @@ class MilestoneViewSet(HistoryResourceMixin, WatchedResourceMixin, ModelCrudView
qs = qs.prefetch_related("user_stories",
"user_stories__role_points",
"user_stories__role_points__points",
"user_stories__role_points__role")
"user_stories__role_points__role",
"user_stories__generated_from_issue",
"user_stories__project",
"watchers",
"user_stories__watchers")
qs = qs.select_related("project")
qs = qs.order_by("-estimated_start")
return qs

View File

@ -91,46 +91,62 @@ class Milestone(WatchedModelMixin, models.Model):
@property
def total_points(self):
return self._get_user_stories_points(
[us for us in self.user_stories.all().prefetch_related('role_points', 'role_points__points')]
[us for us in self.user_stories.all()]
)
@property
def closed_points(self):
return self._get_user_stories_points(
[us for us in self.user_stories.all().prefetch_related('role_points', 'role_points__points') if us.is_closed]
[us for us in self.user_stories.all() if us.is_closed]
)
def _get_points_increment(self, client_requirement, team_requirement):
def _get_increment_points(self):
if hasattr(self, "_increments"):
return self._increments
self._increments = {
"client_increment": {},
"team_increment": {},
"shared_increment": {},
}
user_stories = UserStory.objects.none()
if self.estimated_start and self.estimated_finish:
user_stories = UserStory.objects.filter(
created_date__gte=self.estimated_start,
created_date__lt=self.estimated_finish,
project_id=self.project_id,
client_requirement=client_requirement,
team_requirement=team_requirement
).prefetch_related('role_points', 'role_points__points')
return self._get_user_stories_points(user_stories)
user_stories = filter(
lambda x: x.created_date.date() >= self.estimated_start and x.created_date.date() < self.estimated_finish,
self.project.user_stories.all()
)
self._increments['client_increment'] = self._get_user_stories_points(
[us for us in user_stories if us.client_requirement is True and us.team_requirement is False]
)
self._increments['team_increment'] = self._get_user_stories_points(
[us for us in user_stories if us.client_requirement is False and us.team_requirement is True]
)
self._increments['shared_increment'] = self._get_user_stories_points(
[us for us in user_stories if us.client_requirement is True and us.team_requirement is True]
)
return self._increments
@property
def client_increment_points(self):
client_increment = self._get_points_increment(True, False)
self._get_increment_points()
client_increment = self._get_increment_points()["client_increment"]
shared_increment = {
key: value/2 for key, value in self.shared_increment_points.items()
key: value/2 for key, value in self._get_increment_points()["shared_increment"].items()
}
return dict_sum(client_increment, shared_increment)
@property
def team_increment_points(self):
team_increment = self._get_points_increment(False, True)
team_increment = self._get_increment_points()["team_increment"]
shared_increment = {
key: value/2 for key, value in self.shared_increment_points.items()
key: value/2 for key, value in self._get_increment_points()["shared_increment"].items()
}
return dict_sum(team_increment, shared_increment)
@property
def shared_increment_points(self):
return self._get_points_increment(True, True)
return self._get_increment_points()["shared_increment"]
def closed_points_by_date(self, date):
return self._get_user_stories_points([

View File

@ -254,23 +254,20 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
return dict_sum(*flat_role_dicts)
def _get_points_increment(self, client_requirement, team_requirement):
userstory_model = apps.get_model("userstories", "UserStory")
user_stories = userstory_model.objects.none()
last_milestones = self.milestones.order_by('-estimated_finish')
last_milestone = last_milestones[0] if last_milestones else None
if last_milestone:
user_stories = userstory_model.objects.filter(
user_stories = self.user_stories.filter(
created_date__gte=last_milestone.estimated_finish,
project_id=self.id,
client_requirement=client_requirement,
team_requirement=team_requirement
).prefetch_related('role_points', 'role_points__points')
)
else:
user_stories = userstory_model.objects.filter(
project_id=self.id,
user_stories = self.user_stories.filter(
client_requirement=client_requirement,
team_requirement=team_requirement
).prefetch_related('role_points', 'role_points__points')
)
user_stories = user_stories.prefetch_related('role_points', 'role_points__points')
return self._get_user_stories_points(user_stories)
@property
@ -291,15 +288,26 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
@property
def closed_points(self):
return self._get_user_stories_points(self.user_stories.filter(is_closed=True).prefetch_related('role_points', 'role_points__points'))
return self.calculated_points["closed"]
@property
def defined_points(self):
return self._get_user_stories_points(self.user_stories.all().prefetch_related('role_points', 'role_points__points'))
return self.calculated_points["defined"]
@property
def assigned_points(self):
return self._get_user_stories_points(self.user_stories.filter(milestone__isnull=False).prefetch_related('role_points', 'role_points__points'))
return self.calculated_points["assigned"]
@property
def calculated_points(self):
user_stories = self.user_stories.all().prefetch_related('role_points', 'role_points__points')
closed_user_stories = user_stories.filter(is_closed=True)
assigned_user_stories = user_stories.filter(milestone__isnull=False)
return {
"defined": self._get_user_stories_points(user_stories),
"closed": self._get_user_stories_points(closed_user_stories),
"assigned": self._get_user_stories_points(assigned_user_stories),
}
class ProjectModulesConfig(models.Model):

View File

@ -15,12 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db.models import Q, Count
from django.apps import apps
import datetime
import copy
from taiga.projects.history.models import HistoryEntry
def _get_milestones_stats_for_backlog(project):
"""
Get collection of stats for each millestone of project.
@ -37,20 +37,27 @@ def _get_milestones_stats_for_backlog(project):
future_team_increment = sum(project.future_team_increment.values())
future_client_increment = sum(project.future_client_increment.values())
milestones = project.milestones.order_by('estimated_start')
milestones = project.milestones.order_by('estimated_start').\
prefetch_related("user_stories",
"user_stories__role_points",
"user_stories__role_points__points")
milestones = list(milestones)
milestones_count = len(milestones)
optimal_points = 0
team_increment = 0
client_increment = 0
for current_milestone in range(0, max(milestones.count(), project.total_milestones)):
for current_milestone in range(0, max(milestones_count, project.total_milestones)):
optimal_points = (project.total_story_points -
(optimal_points_per_sprint * current_milestone))
evolution = (project.total_story_points - current_evolution
if current_evolution is not None else None)
if current_milestone < milestones.count():
if current_milestone < milestones_count:
ml = milestones[current_milestone]
milestone_name = ml.name
team_increment = current_team_increment
client_increment = current_client_increment
@ -58,6 +65,7 @@ def _get_milestones_stats_for_backlog(project):
current_evolution += sum(ml.closed_points.values())
current_team_increment += sum(ml.team_increment_points.values())
current_client_increment += sum(ml.client_increment_points.values())
else:
milestone_name = "Future sprint"
team_increment = current_team_increment + future_team_increment,
@ -194,7 +202,13 @@ def get_stats_for_project_issues(project):
def get_stats_for_project(project):
closed_points = sum(project.closed_points.values())
project = apps.get_model("projects", "Project").objects.\
prefetch_related("milestones",
"user_stories").\
get(id=project.id)
points = project.calculated_points
closed_points = sum(points["closed"].values())
closed_milestones = project.milestones.filter(closed=True).count()
speed = 0
if closed_milestones != 0:
@ -205,11 +219,11 @@ def get_stats_for_project(project):
'total_milestones': project.total_milestones,
'total_points': project.total_story_points,
'closed_points': closed_points,
'closed_points_per_role': project.closed_points,
'defined_points': sum(project.defined_points.values()),
'defined_points_per_role': project.defined_points,
'assigned_points': sum(project.assigned_points.values()),
'assigned_points_per_role': project.assigned_points,
'closed_points_per_role': points["closed"],
'defined_points': sum(points["defined"].values()),
'defined_points_per_role': points["defined"],
'assigned_points': sum(points["assigned"].values()),
'assigned_points_per_role': points["assigned"],
'milestones': _get_milestones_stats_for_backlog(project),
'speed': speed,
}

View File

@ -59,10 +59,10 @@ class UserStoryViewSet(OCCResourceMixin, HistoryResourceMixin, WatchedResourceMi
def get_queryset(self):
qs = self.model.objects.all()
qs = qs.prefetch_related("points",
"role_points",
qs = qs.prefetch_related("role_points",
"role_points__points",
"role_points__role")
"role_points__role",
"watchers")
qs = qs.select_related("milestone", "project")
return qs

View File

@ -124,8 +124,7 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
return self.role_points
def get_total_points(self):
not_null_role_points = self.role_points.select_related("points").\
exclude(points__value__isnull=True)
not_null_role_points = [rp for rp in self.role_points.all() if rp.points.value is not None]
#If we only have None values the sum should be None
if not not_null_role_points: