2011-08-11 78 views
1

我正在用django写博客,并且在博客条目的底部,我想显示相对于我使用django-taggit附加的标签的5个最新条目。django templatetag,获取与当前帖子的taggit标签相关的帖子

所以我想我需要通过当前的博客条目(我们正在查看)到一个模板标签,将检索具有相同taggit标签的条目,或足够接近。但是让我们从简单的开始,并说检索共享第一个taggit标签的条目。

这就是我想出了:

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]) 

但它不会做任何事情。通过print语句逐句通过它,我可以看到它通过init获得到RecentContentNode,但不到render方法。我没有得到任何错误或警告,所以我不知道会发生什么。但我认为这是变量/解决这个问题,因为我看到其他人通过网络出现类似的问题,但他们经常回应说,他们固定它的帖子,但不是如何,所以我不明智。

我错过了什么?或者有更好的方法..

回答

2

您可以直接在上下文中传递列表。如果你正在使用基于类的通用视图,传递一个

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

只应在视图中,你真的需要它添加此,并定制需要显示什么,而不是盲目地添加此在任何视图的背景下。

+0

你说得对。我立场纠正。 – rewritten

+0

完美地工作,但告诉我为什么我应该小心使用这种方法?它是否存在安全风险?还是会增加额外的数据库查询/开销? – mXed

+0

重点是开销。如果您可以根据某些上下文信息选择是否包含related_entries,则可以保存一个或两个查询。 – rewritten