views:

119

answers:

1

Couldn't think of a more appropriate question title, but I'm looking for some advice on how to implement the following requirement:

I have a Project class, which may contain Task objects. Tasks have an assignee. In my Django template, I'd like to render a 'tree' of projects and tasks for a given user, showing only those projects that have at least one task assigned to the user, and within each project, only those tasks assigned to the user.

My initial approach was to first find projects with at least one assigned task:

def list_assigned_tasks(request, assignee_id):
    projects = Project.objects.filter(task__assignee=assignee_id).distinct()
    # ...

(Not the most efficient approach, but I'm only dealing with small numbers of projects & tasks.)

Then I thought I might write a method on Project to retrieve only those tasks assigned to a user:

class Project(models.Model):
    # ...
    def assigned_tasks(self, assignee_id):
        return self.task_set.filter(assignee=assignee_id)

or something like that.

However, I wouldn't be able to call that method directly from within a template. So, my question is: is there a better way of achieving this? Looking for advice on the QuerySet and template implementation.

(My other thought was to just bolt the assigned tasks onto each project instance in list_assigned_tasks - is that a valid approach?)

+1  A: 

To get a list of tasks that are assigned to a user, I would do something along these lines:

assignee = get_object_or_404(Person, pk=assignee_id)
tasks = assignee.task_set.select_related('project').order_by('project')

Then in the template:

{% regroup tasks by project as project_list %}
{% for pgroup in project_list %}
    <h3>{{ pgroup.grouper }}</h3>
    <ul>
    {% for task in pgroup.list %}
       <li>{{ task }}</li>
    {% endfor %}
    </ul>
{% endfor %}

You may have to adjust some details for your implementation but you get the idea I hope.

Wogan
Ah, excellent. I wasn't aware of `regroup` - that looks like just the thing, thanks.
harto