comparison forums/views/main.py @ 791:0ca691cccf8d

Utilize select_related() for user & user profiles. This commit also removes the caching of the avatar URL in the avatar template tag. This is because we are now using select_related, so we already have the profile & avatar when we get to the tag. Thus we don't need to waste time querying the cache. Removed an apparently unused member map template as well.
author Brian Neal <bgneal@gmail.com>
date Fri, 23 May 2014 21:52:41 -0500
parents 9e803323a0d0
children 71a671dab55d 4619290d171d
comparison
equal deleted inserted replaced
790:6a06080e7ca8 791:0ca691cccf8d
21 from django.views.decorators.http import require_POST 21 from django.views.decorators.http import require_POST
22 from django.db.models import F 22 from django.db.models import F
23 23
24 import antispam 24 import antispam
25 import antispam.utils 25 import antispam.utils
26 from bio.models import UserProfile, BadgeOwnership 26 from bio.models import BadgeOwnership
27 from core.paginator import DiggPaginator 27 from core.paginator import DiggPaginator
28 from core.functions import email_admins, quote_message 28 from core.functions import email_admins, quote_message
29 29
30 from forums.models import (Forum, Topic, Post, FlaggedPost, TopicLastVisit, 30 from forums.models import (Forum, Topic, Post, FlaggedPost, TopicLastVisit,
31 ForumLastVisit, Attachment) 31 ForumLastVisit)
32 from forums.forms import (NewTopicForm, NewPostForm, PostForm, MoveTopicForm, 32 from forums.forms import (NewTopicForm, NewPostForm, PostForm, MoveTopicForm,
33 SplitTopicForm) 33 SplitTopicForm)
34 from forums.unread import (get_forum_unread_status, get_topic_unread_status, 34 from forums.unread import (get_forum_unread_status, get_topic_unread_status,
35 get_post_unread_status, get_unread_topics) 35 get_post_unread_status, get_unread_topics)
36 36
168 return HttpResponseForbidden() 168 return HttpResponseForbidden()
169 169
170 topic.view_count = F('view_count') + 1 170 topic.view_count = F('view_count') + 1
171 topic.save(force_update=True) 171 topic.save(force_update=True)
172 172
173 posts = topic.posts.select_related('user') 173 posts = topic.posts.\
174 select_related('user', 'user__profile').\
175 prefetch_related('attachments')
174 176
175 paginator = create_post_paginator(posts) 177 paginator = create_post_paginator(posts)
176 page_num = get_page_num(request) 178 page_num = get_page_num(request)
177 try: 179 try:
178 page = paginator.page(page_num) 180 page = paginator.page(page_num)
179 except InvalidPage: 181 except InvalidPage:
180 raise Http404 182 raise Http404
181 get_post_unread_status(topic, page.object_list, request.user) 183 get_post_unread_status(topic, page.object_list, request.user)
182 184
183 # Attach user profiles to each post's user to avoid using 185 # Get the BadgeOwnership & Badges for each user who has posted in the
184 # get_user_profile() in the template. 186 # thread. This is done to save SQL queries in the template.
185 users = set(post.user.id for post in page.object_list)
186
187 profiles = UserProfile.objects.filter(user__id__in=users).select_related()
188 profile_keys = [profile.id for profile in profiles]
189 user_profiles = dict((profile.user.id, profile) for profile in profiles)
190 187
191 last_post_on_page = None 188 last_post_on_page = None
189 profile_ids = []
192 for post in page.object_list: 190 for post in page.object_list:
193 post.user.user_profile = user_profiles[post.user.id]
194 post.attach_list = []
195 last_post_on_page = post 191 last_post_on_page = post
196 192 profile_ids.append(post.user.profile.pk)
197 # Attach badge ownership info to the user profiles to avoid lots 193
198 # of database hits in the template: 194 bo_qs = BadgeOwnership.objects.filter(profile__in=profile_ids).\
199 bos_qs = BadgeOwnership.objects.filter( 195 select_related()
200 profile__id__in=profile_keys).select_related()
201 bos = collections.defaultdict(list) 196 bos = collections.defaultdict(list)
202 for bo in bos_qs: 197 for bo in bo_qs:
203 bos[bo.profile.id].append(bo) 198 bos[bo.profile.pk].append(bo)
204 199
205 for user_id, profile in user_profiles.iteritems(): 200 for post in page.object_list:
206 profile.badge_ownership = bos[profile.id] 201 post.user.profile.badge_ownership = bos[post.user.profile.pk]
207
208 # Attach any attachments
209 post_ids = [post.pk for post in page.object_list]
210 attachments = Attachment.objects.filter(post__in=post_ids).select_related(
211 'embed').order_by('order')
212
213 post_dict = dict((post.pk, post) for post in page.object_list)
214 for item in attachments:
215 post_dict[item.post.id].attach_list.append(item.embed)
216 202
217 last_page = page_num == paginator.num_pages 203 last_page = page_num == paginator.num_pages
218 204
219 if request.user.is_authenticated(): 205 if request.user.is_authenticated():
220 if last_page or last_post_on_page is None: 206 if last_page or last_post_on_page is None:
465 form.attach_proc.save_attachments(post) 451 form.attach_proc.save_attachments(post)
466 452
467 return HttpResponseRedirect(post.get_absolute_url()) 453 return HttpResponseRedirect(post.get_absolute_url())
468 else: 454 else:
469 form = PostForm(instance=post, topic_name=topic_name) 455 form = PostForm(instance=post, topic_name=topic_name)
470
471 post.user.user_profile = post.user.profile
472 456
473 return render_to_response('forums/edit_post.html', { 457 return render_to_response('forums/edit_post.html', {
474 'forum': post.topic.forum, 458 'forum': post.topic.forum,
475 'topic': post.topic, 459 'topic': post.topic,
476 'post': post, 460 'post': post,