Question

I am writing a blog with django, and at the bottom of a blog entry i want to display the 5 latest entries relative to the tags i have attached using django-taggit.

So i figured i needed to pass the current blog entry (the one we are viewing) to a templatetag that would retrieve entries with the same taggit-tags, or close enough. But lets start out simple and say retrieve entries that share the first taggit-tag.

this is what i came up with:

from django.template import Library, Node
from django import template
from blog.models import Entry

register = Library()

class RecentContentNode(Node):
    def __init__(self, num, object, varname):
        self.object = template.Variable(object)
        self.num, self.varname = num, varname

    def render(self, context):
        object = self.object.resolve(context)
        tag_list = object.tags.all()
        tag_names = tag_list[0].name
        context[self.varname] = Entry.objects.filter(tags__name__in=[tag_names])[:self.num]
        return ''

@register.tag
def get_recent_related(parser, token):
    bits = token.contents.split()
    if len(bits) != 5:
        raise TemplateSyntaxError, "get_latest_entries tag takes exactly four arguments"
    if bits[3] != 'as':
        raise TemplateSyntaxError, "fourth argument to the get_recent tag must be 'as'"
    return RecentContentNode(bits[1], bits[2], bits[4])

But it doesn't do anything. Stepping through it with print statement I can see it gets to the RecentContentNode, through the init but not into the render method. I get no errors or warnings so i don't know what happens. But i think it's the Variable / resolve thats the problem, since i see other people through out the net having similar problems, but they often respond to the post saying that they fixed it, but not how, so im no wiser.

Something obvious i missed? or is there a better way ..

Was it helpful?

Solution

You can pass the list directly in the context. If you are using class-based generic views, pass an

def get_context_data(self, **kwargs):
    context_data = super(EntryView, self).get_context_data(**kwargs)
    related_entries = Entry.objects.filter(
        tags__name__in=list(self.object.tags.values_list('name', flat=True))
    ).exclude(id=self.object.id)
    context_data['related_entries'] = related_entries
    return context_data

https://docs.djangoproject.com/en/dev/topics/class-based-views/#adding-extra-context

You should add this only in views where you really need it, and tailor to what you need to display, not blindly add this in the context of any view whatever the view is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top