diff options
-rw-r--r-- | main/models.py | 13 | ||||
-rw-r--r-- | packages/utils.py | 1 | ||||
-rw-r--r-- | todolists/views.py | 8 |
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: |