bgneal@399: """ bgneal@399: Common utility/helper code for the news app. bgneal@399: bgneal@399: """ bgneal@399: from django.contrib.contenttypes.models import ContentType bgneal@399: bgneal@399: from comments.models import Comment bgneal@399: from tagging.models import TaggedItem bgneal@399: from news.models import Story bgneal@399: bgneal@399: bgneal@399: def attach_extra_attrs(stories): bgneal@399: """ bgneal@399: For each story in the input stories list, attach 2 new attributes: bgneal@399: tag_list and comment_count. The tags and comment count info is pulled from bgneal@399: the database in bulk. This saves database queries when lots of news bgneal@399: stories are displayed at once. For best results, use ".defer('tags')" bgneal@399: when retrieve the stories from the database. bgneal@399: bgneal@399: """ bgneal@399: stories_dict = dict((story.id, story) for story in stories) bgneal@399: story_ids = stories_dict.keys() bgneal@399: bgneal@399: # Get all the tags out in one query bgneal@399: ct = ContentType.objects.get_for_model(Story) bgneal@399: tagged_items = TaggedItem.objects.filter(content_type=ct, bgneal@399: object_id__in=story_ids).select_related('tag') bgneal@399: bgneal@399: for story in stories_dict.values(): bgneal@399: story.tag_list = [] bgneal@399: story.comment_count = 0 bgneal@399: bgneal@399: # attach tags bgneal@399: for item in tagged_items: bgneal@399: stories_dict[item.object_id].tag_list.append(item.tag.name) bgneal@399: bgneal@399: # Now get all the comment counts out in one fell swoop bgneal@399: bgneal@399: story_ids = Comment.objects.filter(content_type=ct, bgneal@399: object_id__in=story_ids).values_list('object_id', flat=True) bgneal@399: bgneal@399: # compute comment_count bgneal@399: for story_id in story_ids: bgneal@399: stories_dict[story_id].comment_count += 1