Index: remit/finance_core/reporting.py
===================================================================
--- remit/finance_core/reporting.py	(revision 13e7c01b660cce664c1e5dd05f2fed24c272a1a1)
+++ remit/finance_core/reporting.py	(revision 13e7c01b660cce664c1e5dd05f2fed24c272a1a1)
@@ -0,0 +1,46 @@
+from decimal import Decimal
+from django.db.models import Sum
+
+def build_table_annotate(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis, ):
+    # Setup
+    arcprimary = {}
+    table = []
+    zero = Decimal('0.00')
+    for num, (pk, label, qobj, ) in enumerate(primary_axis):
+        arcprimary[pk] = num
+        table.append([zero]*len(secondary_axis))
+
+    def lineitem_total(obj):
+        if obj.lineitem__amount__sum is None: return zero
+        else: return obj.lineitem__amount__sum
+
+    # Do the real work
+    print secondary_axis
+    for num, (label, qobj_lineitem, qobj_primary) in enumerate(secondary_axis):
+        print num
+        secondary_results = (primary_axis_objs.filter(main_lineitem_limit_primary, qobj_primary, ).annotate(Sum('lineitem__amount')))
+        for cell in secondary_results:
+            #print cell, cell.pk, arcprimary[cell.pk], num, table[arcprimary[cell.pk]]
+            table[arcprimary[cell.pk]][num] = lineitem_total(cell)
+
+    return table
+
+def build_table_aggregate(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis):
+    # This uses a simpler but probably slower method
+    # In theory, if we grow unit tests, comparing this method with
+    # the one above using annotate would be a good idea
+    zero = Decimal('0.00')
+    def total_amount(queryset):
+        amount = queryset.aggregate(Sum('amount'))['amount__sum']
+        if amount is None: return zero
+        else: return amount
+    table = [ # Primary axis
+            [ # Secondary axis
+                total_amount(line_items.filter(primary[2], secondary[1]))
+            for secondary in secondary_axis]
+        for primary in primary_axis]
+
+    return table
+    
+
+build_table = build_table_annotate
Index: remit/finance_core/views.py
===================================================================
--- remit/finance_core/views.py	(revision 3f1e074e87d8fa243ea7feb919a4612d85290815)
+++ remit/finance_core/views.py	(revision 13e7c01b660cce664c1e5dd05f2fed24c272a1a1)
@@ -5,6 +5,7 @@
 from django.template import RequestContext
 from django.http import Http404, HttpResponseRedirect
-from django.db.models import Q, Sum
+from django.db.models import Q
 from decimal import Decimal
+import finance_core.reporting
 
 def display_tree(request):
@@ -15,10 +16,15 @@
     line_items = finance_core.models.LineItem.objects.all()
     term_name = 'All'
-    term_primary_Q = Q()
+    compute_method = 'default'
+
+    # Main limit to lineitems, relative to primary axis
+    main_lineitem_limit_primary = Q()
+    if 'compute_method' in request.REQUEST:
+        compute_method = request.REQUEST['compute_method']
     if 'term' in request.REQUEST:
         term_obj = get_object_or_404(finance_core.models.BudgetTerm, slug=request.REQUEST['term'])
         term_name = term_obj.name
         line_items = line_items.filter(budget_term=term_obj)
-        term_primary_Q = Q(lineitem__budget_term=term_obj)
+        main_lineitem_limit_primary = Q(lineitem__budget_term=term_obj)
     if 'area' in request.REQUEST:
         base_area_obj = get_object_or_404(finance_core.models.BudgetArea, pk=request.REQUEST['area'])
@@ -27,6 +33,7 @@
     line_items = line_items.filter(budget_area__in=base_area_obj.get_descendants())
     base_area_depth = base_area_obj.depth
-    print base_area_obj
+    #print base_area_obj
 
+    # Initialize the axis
     primary_name = 'Budget Areas'
     primary_axis = [
@@ -43,42 +50,22 @@
         for layer in finance_core.models.layers
     ]
-
     secondary_axis.append(('Total', Q(), Q()))
 
     primary_labels = [ ]
-    arcprimary = {}
-    table = []
-    zero = Decimal('0.00')
     for num, (pk, label, qobj, ) in enumerate(primary_axis):
         primary_labels.append(label)
-        arcprimary[pk] = num
-        table.append([zero]*len(secondary_axis))
-    print arcprimary
-
     secondary_labels = [ secondary[0] for secondary in secondary_axis ]
 
-    def lineitem_total(obj):
-        if obj.lineitem__amount__sum is None: return zero
-        else: return obj.lineitem__amount__sum
-    for num, (label, qobj_lineitem, qobj_primary) in enumerate(secondary_axis):
-        secondary_results = (primary_axis_objs.filter(qobj_primary, term_primary_Q).annotate(Sum('lineitem__amount')))
-        for cell in secondary_results:
-            print cell, cell.pk, arcprimary[cell.pk], num, table[arcprimary[cell.pk]]
-            table[arcprimary[cell.pk]][num] = lineitem_total(cell)
-
-    slow = False
-    if slow:
-        # This uses a simpler but probably slower method
-        # In theory, if we grow unit tests, comparing this method with
-        # the one above using annotate would be a good idea
-        def total_amount(queryset):
-            amount = queryset.aggregate(Sum('amount'))['amount__sum']
-            if amount is None: return zero
-            else: return amount
-        table = [ # Primary axis
-                [ # Secondary axis
-                    total_amount(line_items.filter(primary[1], secondary[1]))
-                for secondary in secondary_axis]
-            for primary in primary_axis]
+    # Do the computation
+    compute_methods = {
+        'default':   finance_core.reporting.build_table,
+        'aggregate': finance_core.reporting.build_table_aggregate,
+        'annotate':  finance_core.reporting.build_table_annotate,
+    }
+    if compute_method in compute_methods:
+        build_table = compute_methods[compute_method]
+    else:
+        raise Http404("Unknown compute_method selected")
+    table = build_table(line_items, main_lineitem_limit_primary, primary_axis, primary_axis_objs, secondary_axis, )
 
     debug = False
