# HG changeset patch # User Brian Neal # Date 1400899961 18000 # Node ID 0ca691cccf8d2f040b6200e1fc468eff385c8d6b # Parent 6a06080e7ca8c92a2a54b0bbb7b78e9e3e0151f9 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. diff -r 6a06080e7ca8 -r 0ca691cccf8d bio/templatetags/bio_tags.py --- a/bio/templatetags/bio_tags.py Fri May 23 15:39:14 2014 -0500 +++ b/bio/templatetags/bio_tags.py Fri May 23 21:52:41 2014 -0500 @@ -30,28 +30,15 @@ @register.inclusion_tag('bio/avatar_tag.html') def avatar(user, profile_link=True, align='bottom'): """ - Returns a dict of attributes for a user's avatar image. + Renders a user's avatar image. - If the user object has an attribute 'user_profile', this is assumed to be - the user's profile that has been pre-fetched. Otherwise, the cache is - consulted to retrieve the avatar info for the user. If there is a cache - miss, only then will we access the profile attribute to retrieve the profile - from the database. + For best results, ensure the user's profile has already been loaded (perhaps + via a select_related()). We no longer cache the avatar url because with + proper use of select_related we will have the user profile already so there + is no need to go spend time checking the cache. """ - # img_info is a tuple that contains info about the avatar: - # (url, width, height) - - if hasattr(user, 'user_profile'): - img_url = get_img_url(user.user_profile) - else: - # try the cache - cache_key = 'avatar_' + user.username - img_url = cache.get(cache_key) - if img_url is None: - profile = user.profile - img_url = get_img_url(profile) - cache.set(cache_key, img_url) + img_url = get_img_url(user.profile) title = user.username style = '' diff -r 6a06080e7ca8 -r 0ca691cccf8d comments/templatetags/comment_tags.py --- a/comments/templatetags/comment_tags.py Fri May 23 15:39:14 2014 -0500 +++ b/comments/templatetags/comment_tags.py Fri May 23 21:52:41 2014 -0500 @@ -160,7 +160,7 @@ Syntax: {% render_comment_list [object] %} """ - qs = Comment.objects.for_object(object).select_related('user') + qs = Comment.objects.for_object(object).select_related('user', 'user__profile') return { 'comments': qs, 'STATIC_URL': settings.STATIC_URL, diff -r 6a06080e7ca8 -r 0ca691cccf8d forums/views/main.py --- a/forums/views/main.py Fri May 23 15:39:14 2014 -0500 +++ b/forums/views/main.py Fri May 23 21:52:41 2014 -0500 @@ -23,12 +23,12 @@ import antispam import antispam.utils -from bio.models import UserProfile, BadgeOwnership +from bio.models import BadgeOwnership from core.paginator import DiggPaginator from core.functions import email_admins, quote_message from forums.models import (Forum, Topic, Post, FlaggedPost, TopicLastVisit, - ForumLastVisit, Attachment) + ForumLastVisit) from forums.forms import (NewTopicForm, NewPostForm, PostForm, MoveTopicForm, SplitTopicForm) from forums.unread import (get_forum_unread_status, get_topic_unread_status, @@ -170,7 +170,9 @@ topic.view_count = F('view_count') + 1 topic.save(force_update=True) - posts = topic.posts.select_related('user') + posts = topic.posts.\ + select_related('user', 'user__profile').\ + prefetch_related('attachments') paginator = create_post_paginator(posts) page_num = get_page_num(request) @@ -180,39 +182,23 @@ raise Http404 get_post_unread_status(topic, page.object_list, request.user) - # Attach user profiles to each post's user to avoid using - # get_user_profile() in the template. - users = set(post.user.id for post in page.object_list) - - profiles = UserProfile.objects.filter(user__id__in=users).select_related() - profile_keys = [profile.id for profile in profiles] - user_profiles = dict((profile.user.id, profile) for profile in profiles) + # Get the BadgeOwnership & Badges for each user who has posted in the + # thread. This is done to save SQL queries in the template. last_post_on_page = None + profile_ids = [] for post in page.object_list: - post.user.user_profile = user_profiles[post.user.id] - post.attach_list = [] last_post_on_page = post + profile_ids.append(post.user.profile.pk) - # Attach badge ownership info to the user profiles to avoid lots - # of database hits in the template: - bos_qs = BadgeOwnership.objects.filter( - profile__id__in=profile_keys).select_related() + bo_qs = BadgeOwnership.objects.filter(profile__in=profile_ids).\ + select_related() bos = collections.defaultdict(list) - for bo in bos_qs: - bos[bo.profile.id].append(bo) + for bo in bo_qs: + bos[bo.profile.pk].append(bo) - for user_id, profile in user_profiles.iteritems(): - profile.badge_ownership = bos[profile.id] - - # Attach any attachments - post_ids = [post.pk for post in page.object_list] - attachments = Attachment.objects.filter(post__in=post_ids).select_related( - 'embed').order_by('order') - - post_dict = dict((post.pk, post) for post in page.object_list) - for item in attachments: - post_dict[item.post.id].attach_list.append(item.embed) + for post in page.object_list: + post.user.profile.badge_ownership = bos[post.user.profile.pk] last_page = page_num == paginator.num_pages @@ -468,8 +454,6 @@ else: form = PostForm(instance=post, topic_name=topic_name) - post.user.user_profile = post.user.profile - return render_to_response('forums/edit_post.html', { 'forum': post.topic.forum, 'topic': post.topic, diff -r 6a06080e7ca8 -r 0ca691cccf8d membermap/views.py --- a/membermap/views.py Fri May 23 15:39:14 2014 -0500 +++ b/membermap/views.py Fri May 23 21:52:41 2014 -0500 @@ -57,9 +57,10 @@ return HttpResponse(s, content_type='application/json') # Compute JSON for the map - entries = MapEntry.objects.all().select_related().order_by('user__username') + entries = MapEntry.objects.select_related('user', 'user__profile').\ + order_by('user__username') users = [] - user_ids = [] + avatar_urls = [] recent = [] for entry in entries.iterator(): users.append(dict(name=entry.user.username, @@ -67,20 +68,17 @@ lon=entry.lon, message=entry.html, )) - user_ids.append(entry.user.id) + avatar = entry.user.profile.avatar + if avatar and avatar.url: + avatar_urls.append(avatar.url) + else: + avatar_urls.append(None) recent.append((entry.date_updated, entry.user.username)) - # Get avatars for all users - profiles = UserProfile.objects.filter(user__in=user_ids).select_related() - avatars = {} - for profile in profiles.iterator(): - if profile.avatar and profile.avatar.url: - avatars[profile.user.username] = profile.avatar.url - # Render the messages that go in the balloons - for user in users: + for user, avatar_url in zip(users, avatar_urls): user['message'] = render_to_string('membermap/balloon.html', - dict(user=user, avatar_url=avatars.get(user['name']))) + dict(user=user, avatar_url=avatar_url)) # Produce the list of recent updates recent.sort(reverse=True) diff -r 6a06080e7ca8 -r 0ca691cccf8d sg101/templates/forums/display_post.html --- a/sg101/templates/forums/display_post.html Fri May 23 15:39:14 2014 -0500 +++ b/sg101/templates/forums/display_post.html Fri May 23 21:52:41 2014 -0500 @@ -6,27 +6,27 @@ {% profile_link post.user.username %}
{% avatar post.user %}
Joined: {{ post.user.date_joined|date:"M d, Y" }}
- Posts: {{ post.user.user_profile.forum_post_count }}
- {% if post.user.user_profile.location %} - {{ post.user.user_profile.location }}
+ Posts: {{ post.user.profile.forum_post_count }}
+ {% if post.user.profile.location %} + {{ post.user.profile.location }}
{% endif %} - {% if post.user.user_profile.country %} - {% flag_icon post.user.user_profile.country 'small' %}
+ {% if post.user.profile.country %} + {% flag_icon post.user.profile.country 'small' %}
{% endif %} - {% for bo in post.user.user_profile.badge_ownership %} + {% for bo in post.user.profile.badge_ownership %} {{ bo.badge_count_str }} {% endfor %} {% if user.is_authenticated %}

PM - {% if not post.user.user_profile.hide_email %} + {% if not post.user.profile.hide_email %} Email{% endif %}

{% endif %} -
+
{{ post.html|safe }} - {% if post.user.user_profile.signature_html %} - —{{ post.user.user_profile.signature_html|safe }} + {% if post.user.profile.signature_html %} + —{{ post.user.profile.signature_html|safe }} {% endif %} {% if post.has_been_edited %}

Last edited: {{ post.update_date|date:"M d, Y H:i:s" }}

{% endif %}
- {% if post.attach_list %} + {% if post.attachments.all %}
- {% for item in post.attach_list %} + {% for item in post.attachments.all %}
{{ item.html|safe }}
{% endfor %}
@@ -60,7 +60,7 @@ {% if can_moderate %} Delete post - {% if post.user != user and post.user.user_profile.is_stranger %} + {% if post.user != user and post.user.profile.is_stranger %}
Stranger options: diff -r 6a06080e7ca8 -r 0ca691cccf8d sg101/templates/membermap/markdown.html --- a/sg101/templates/membermap/markdown.html Fri May 23 15:39:14 2014 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -{% load markup %} -{% load smiley_tags %} -{% load bio_tags %} -{% avatar user 0 "left" %}{% profile_link user.username %}:
{{ msg|safe }} diff -r 6a06080e7ca8 -r 0ca691cccf8d shoutbox/models.py --- a/shoutbox/models.py Fri May 23 15:39:14 2014 -0500 +++ b/shoutbox/models.py Fri May 23 21:52:41 2014 -0500 @@ -31,7 +31,7 @@ def save(self, *args, **kwargs): if not self.id: self.shout_date = datetime.datetime.now() - self.html = urlize(smilify_html(escape(self.shout)), trim_url_limit=15, + self.html = urlize(smilify_html(escape(self.shout)), trim_url_limit=15, nofollow=True) super(Shout, self).save(*args, **kwargs) diff -r 6a06080e7ca8 -r 0ca691cccf8d shoutbox/views.py --- a/shoutbox/views.py Fri May 23 15:39:14 2014 -0500 +++ b/shoutbox/views.py Fri May 23 21:52:41 2014 -0500 @@ -54,7 +54,8 @@ def view_history(request): """This view allows one to view the shoutbox history.""" - paginator = DiggPaginator(Shout.objects.all().select_related(), + qs = Shout.objects.select_related('user', 'user__profile') + paginator = DiggPaginator(qs, SHOUTS_PER_PAGE, body=5, tail=3, margin=3, padding=2) page = get_page(request.GET) try: @@ -66,7 +67,7 @@ 'page': the_page, }, context_instance = RequestContext(request)) - + shout_id_re = re.compile(r'shout-(\d+)')