I'm developing a time-tracking app, and I've run into some performance
issues.. In my models I have that a Project (e.g. "customer A,
research") can be a member of a ProjectCategory (e.g. "customer A"),
and that each work-unit (Checkin) includes who worked, when they
started, when they stopped and which project they were working on:
class Project(models.Model):
name = models.CharField(maxlength=25)
class ProjectCategory(models.Model):
name = models.CharField(maxlength=25)
projects = models.ManyToManyField(Project)
code = models.CharField(maxlength=10)
class Checkin(models.Model):
who = models.ForeignKey(User) # django.auth.models.User
start_work = models.DateTimeField()
stop_work = models.DateTimeField(null=True, blank=True)
project = models.ForeignKey(Project, null=True, blank=True)
@property #helper fn to get date this checkin is about
def date(self):
return self.start_work.date()
so far so good. I do a lot of manipulation on groups of Checkin
objects, so I've pulled that out into a class (it's much faster to do
this in Python than to hit the database):
class Checkins(list):
@classmethod
def for_user(cls, who):
return cls(Checkin.objects.select_related().filter(who=who))
def __init__(self, checkins): # not sure if this is still needed
for c in checkins:
self.append(c)
def select_date(self): # grab individual dates in self
return sorted(set(d.date for d in self))
def filter_date(self, d):
tmp = Checkins(c for c in self if c.date == d)
tmp.date = d
return tmp
def group_dates(self):
return [self.filter_date(d) for d in self.select_dates()]
Now I want to mark a calendar if a user has worked in a
ProjectCategory on a specific date... something like:
def markable(checkins, project_category):
projects = project_category.projects.all()
res = []
for day in checkins.group_dates():
for ci in day: # for every checkin that day
if ci.project in projects: # <-- HERE
res.append(day.date)
break
return res
at the point marked with # <-- HERE the database gets hit for every
single checkin :-(
0.125 SELECT `tt_project`.`id`,`tt_project`.`name` FROM `tt_project`
WHERE (`tt_project`.`id` = 1)
0.094 SELECT `tt_project`.`id`,`tt_project`.`name` FROM `tt_project`
WHERE (`tt_project`.`id` = 5)
0.109 SELECT `tt_project`.`id`,`tt_project`.`name` FROM `tt_project`
WHERE (`tt_project`.`id` = 1)
... 144 more
I thought I had select_related() in all the right places, but
apparently not... Any pointers would be very welcome.
-- bjorn
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---