2011-08-11 105 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