From 6e441f76721aa7f2b7415d477f4a90592ad87d48 Mon Sep 17 00:00:00 2001 From: Alex Buck <lxbuck@gmail.com> Date: Tue, 5 Jun 2012 11:54:31 +0300 Subject: [PATCH] fix #182: do not check access permissions for every searched topic. patch#2 --- djangobb_forum/util.py | 25 +++++++++++++++++++++++++ djangobb_forum/views.py | 24 ++++++++++-------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/djangobb_forum/util.py b/djangobb_forum/util.py index 7c29bd5..8d59c48 100644 --- a/djangobb_forum/util.py +++ b/djangobb_forum/util.py @@ -221,3 +221,28 @@ def convert_text_to_html(text, markup): else: raise Exception('Invalid markup property: %s' % markup) return urlize(text) + + +class TopicFromPostResult(object): + """ + Custom Result object to return topics from a post search. + + This function uses a generator to return topic objects from + results given by haystack on a post query. This eliminates + loading a large array of topic objects into memory. + """ + + def __init__(self, posts): + self.posts = posts + + def __len__(self): + return len(self.posts) + + def __getitem__(self, key): + if isinstance(key, slice): + return (self.posts[i].object.topic + for i in xrange(*key.indices(len(self)))) + elif isinstance(key, int): + return self.posts[key].object.topic + + raise TypeError('unknown type in key for __getitem__') diff --git a/djangobb_forum/views.py b/djangobb_forum/views.py index ebd374a..12ca280 100644 --- a/djangobb_forum/views.py +++ b/djangobb_forum/views.py @@ -22,7 +22,7 @@ from djangobb_forum.forms import AddPostForm, EditPostForm, UserSearchForm,\ DisplayProfileForm, PrivacyProfileForm, ReportForm, UploadAvatarForm from djangobb_forum.templatetags import forum_extras from djangobb_forum import settings as forum_settings -from djangobb_forum.util import smiles, convert_text_to_html +from djangobb_forum.util import smiles, convert_text_to_html, TopicFromPostResult from djangobb_forum.templatetags.forum_extras import forum_moderated_by from haystack.query import SearchQuerySet, SQ @@ -162,6 +162,11 @@ def search(request): elif search_in == 'topic': query = query.filter(topic=keywords) + # add exlusions for categories user does not have access too + for category in Category.objects.all(): + if not category.has_access(request.user): + query = query.exclude(category=category) + order = {'0': 'created', '1': 'author', '2': 'topic', @@ -172,21 +177,12 @@ def search(request): posts = query.order_by(order) if 'topics' in request.GET['show_as']: - topics = [] - topics_to_exclude = SQ() - #TODO: rewrite - for post in posts: - if post.object.topic not in topics: - if post.object.topic.forum.category.has_access(request.user): - topics.append(post.object.topic) - else: - topics_to_exclude |= SQ(topic=post.object.topic) - - if topics_to_exclude: - posts = posts.exclude(topics_to_exclude) - return render(request, 'djangobb_forum/search_topics.html', {'results': topics}) + return render(request, 'djangobb_forum/search_topics.html', { + 'results': TopicFromPostResult(posts) + }) elif 'posts' in request.GET['show_as']: return render(request, 'djangobb_forum/search_posts.html', {'results': posts}) + return render(request, 'djangobb_forum/search_topics.html', {'results': topics}) else: form = PostSearchForm()