summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-11-03 23:30:16 -0500
committerDan McGee <dan@archlinux.org>2011-11-03 23:30:16 -0500
commit0db2830b8fda4d898a184a31f3375c10f3cc4083 (patch)
treefed2700088e1f03ffcd9af906184d81f199955fc
parent19c2841f20653fd3c59f73fdb16f7f7b1ea15434 (diff)
Make maintainer lookup on todo lists fast
This is rather sick to look at. Sorry, Django gives me no other choice. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--main/models.py13
-rw-r--r--packages/utils.py1
-rw-r--r--todolists/views.py8
3 files changed, 17 insertions, 5 deletions
diff --git a/main/models.py b/main/models.py
index db456c20..caf36be0 100644
--- a/main/models.py
+++ b/main/models.py
@@ -460,12 +460,17 @@ class Todolist(models.Model):
def __unicode__(self):
return self.name
+ _packages = None
+
@property
def packages(self):
- # select_related() does not use LEFT OUTER JOIN for nullable ForeignKey
- # fields. That is why we need to explicitly list the ones we want.
- return TodolistPkg.objects.select_related(
- 'pkg__repo', 'pkg__arch').filter(list=self).order_by('pkg')
+ if not self._packages:
+ # select_related() does not use LEFT OUTER JOIN for nullable
+ # ForeignKey fields. That is why we need to explicitly list the
+ # ones we want.
+ self._packages = TodolistPkg.objects.select_related(
+ 'pkg__repo', 'pkg__arch').filter(list=self).order_by('pkg')
+ return self._packages
@property
def package_names(self):
diff --git a/packages/utils.py b/packages/utils.py
index 0d756a85..4af0f67d 100644
--- a/packages/utils.py
+++ b/packages/utils.py
@@ -156,6 +156,7 @@ def attach_maintainers(packages):
'''Given a queryset or something resembling it of package objects, find all
the maintainers and attach them to the packages to prevent N+1 query
cascading.'''
+ packages = list(packages)
pkgbases = set(p.pkgbase for p in packages)
rels = PackageRelation.objects.filter(type=PackageRelation.MAINTAINER,
pkgbase__in=pkgbases).values_list('pkgbase', 'user_id').distinct()
diff --git a/todolists/views.py b/todolists/views.py
index 8ad7be56..585cefd0 100644
--- a/todolists/views.py
+++ b/todolists/views.py
@@ -12,6 +12,7 @@ from django.template import Context, loader
from django.utils import simplejson
from main.models import Todolist, TodolistPkg, Package
+from packages.utils import attach_maintainers
from .utils import get_annotated_todolists
class TodoListForm(forms.ModelForm):
@@ -49,6 +50,9 @@ def flag(request, listid, pkgid):
@never_cache
def view(request, listid):
todolist = get_object_or_404(Todolist, id=listid)
+ # we don't hold onto the result, but the objects are the same here,
+ # so accessing maintainers in the template is now cheap
+ attach_maintainers(tp.pkg for tp in todolist.packages)
return direct_to_template(request, 'todolists/view.html', {'list': todolist})
@login_required
@@ -163,8 +167,10 @@ def send_todolist_emails(todo_list, new_packages):
def public_list(request):
todo_lists = Todolist.objects.incomplete()
+ # total hackjob, but it makes this a lot less query-intensive.
+ all_pkgs = [tp for tl in todo_lists for tp in tl.packages]
+ attach_maintainers([tp.pkg for tp in all_pkgs])
return direct_to_template(request, "todolists/public_list.html",
{"todo_lists": todo_lists})
-
# vim: set ts=4 sw=4 et: