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 django-users@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to