Mercurial > public > sg101
comparison gpp/forums/feeds.py @ 393:9af6bd45c1f8
Another try at #191 after getting some good advice in a django-users thread.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 24 Mar 2011 00:15:34 +0000 |
parents | 0398aae48807 |
children | 63e4682d6482 |
comparison
equal
deleted
inserted
replaced
392:79240675b903 | 393:9af6bd45c1f8 |
---|---|
2 | 2 |
3 from django.contrib.syndication.views import Feed | 3 from django.contrib.syndication.views import Feed |
4 from django.core.exceptions import ObjectDoesNotExist | 4 from django.core.exceptions import ObjectDoesNotExist |
5 from django.shortcuts import get_object_or_404 | 5 from django.shortcuts import get_object_or_404 |
6 | 6 |
7 from forums.models import Forum | 7 from forums.models import Forum, Topic, Post |
8 from forums.models import Post | |
9 from core.functions import copyright_str | 8 from core.functions import copyright_str |
10 | 9 |
11 | 10 |
12 class ForumsFeed(Feed): | 11 class ForumsFeed(Feed): |
13 """The Feed class for a specific forum""" | 12 """The Feed class for a specific forum""" |
53 return copyright_str() | 52 return copyright_str() |
54 | 53 |
55 def items(self, obj): | 54 def items(self, obj): |
56 if obj is None: | 55 if obj is None: |
57 # return a combined feed of public forum threads | 56 # return a combined feed of public forum threads |
58 # | |
59 # This didn't work real well on InnoDb: | |
60 # items = Post.objects.filter( | |
61 # topic__forum__in=Forum.objects.public_forums()) | |
62 # | |
63 # For some reason, MySQL wasn't using an index when "in" was used. | |
64 # So let's do this the hard way as a work-around: | |
65 | 57 |
66 public_forum_ids = Forum.objects.public_forum_ids() | 58 # This was tricky to do without suffering a large performance |
67 posts = [] | 59 # impact. Because the number of forums is small, MySQL did not |
68 for forum_id in public_forum_ids: | 60 # try to use an index and ended up searching all the topics for |
69 posts.extend(list(Post.objects.filter( | 61 # candidate posts. We work around this first getting a small list |
70 topic__forum=forum_id).order_by('-creation_date').select_related( | 62 # of candidate topics, and then searching them. This is more |
71 'topic', 'user', 'topic__forum')[:30])) | 63 # queries but a *lot* more time efficient. |
72 | 64 |
73 posts.sort(key=lambda x: x.creation_date, reverse=True) | 65 forum_ids = Forum.objects.public_forum_ids() |
74 return posts[:30] | 66 topic_ids = list(Topic.objects.filter(forum__in=forum_ids).order_by( |
67 '-update_date').values_list('id', flat=True)[:30]) | |
68 items = Post.objects.filter(topic__in=topic_ids) | |
75 | 69 |
76 else: | 70 else: |
77 return Post.objects.filter(topic__forum__id=obj.id).order_by( | 71 items = Post.objects.filter(topic__forum=obj) |
78 '-creation_date').select_related('topic', 'user', 'topic__forum')[:30] | 72 |
73 return items.order_by('-creation_date').select_related('topic', 'user', | |
74 'topic__forum')[:30] | |
79 | 75 |
80 def item_title(self, item): | 76 def item_title(self, item): |
81 return item.topic.name | 77 return item.topic.name |
82 | 78 |
83 def item_description(self, item): | 79 def item_description(self, item): |