class LoadTagsForQuerysetNode(Node): context_var = '_queryset_tags' def __init__(self, queryset): self.queryset = Variable(queryset) def render(self, context): queryset = self.queryset.resolve(context) ids = [item.id for item in queryset] if hasattr(queryset, 'model'): model = queryset.model elif len(ids) > 0: model = item.__class__ else: context[self.context_var] = [] return '' ctype = ContentType.objects.get_for_model(model) context[self.context_var] = \ TaggedItem.objects.select_related().filter(content_type=ctype, object_id__in=ids) return '' @register.tag('load_tags_for_queryset') def do_load_tags_for_queryset(parser, token): """ Retrieves lists of ``TaggedItem`` objects associated with the given queryset stores them in a context variable ``_queryset_tags``. Usage:: {% load_tags_for_queryset [queryset] %} Example:: {% load_tags_for_queryset foo_object %} """ bits = token.contents.split() return LoadTagsForQuerysetNode(bits[1]) @register.tag('loaded_tags_for_object') def do_loaded_tags_for_object(parser, token): """ Retrieves a list of ``Tag`` objects associated with an object and stores them in a context variable. Usage:: {% loaded_tags_for_object [object] as [varname] %} Example:: {% loaded_tags_for_object foo_object as tag_list %} """ bits = token.contents.split() if len(bits) != 4: raise TemplateSyntaxError(_('%s tag requires exactly three arguments') % bits[0]) if bits[2] != 'as': raise TemplateSyntaxError(_("second argument to %s tag must be 'as'") % bits[0]) return LoadedTagsForObjectNode(bits[1], bits[3]) class LoadedTagsForObjectNode(Node): def __init__(self, obj, context_var): self.obj = Variable(obj) self.context_var = context_var def render(self, context): obj = self.obj.resolve(context) try: loaded_tageditems = context['_queryset_tags'] except KeyError: raise TemplateSyntaxError, "loaded_tags_for_object called before load_tags_for_queryset" tags_for_object = [taggeditem.tag for taggeditem in loaded_tageditems\ if taggeditem.object_id == obj.id] context[self.context_var] = tags_for_object return ''