代码之家  ›  专栏  ›  技术社区  ›  kovshenin

Django模板变量分辨率

  •  1
  • kovshenin  · 技术社区  · 14 年前

    嘿,Django回来已经一个星期了,所以不要介意我这个问题是否愚蠢,尽管我在stackoverflow和google上搜索时运气不佳。

    我有一个名为Term的简单模型(尝试为我的新闻模块实现标记和类别),还有一个名为taxonomy_list的模板标记,它应该将分配给post的所有术语输出到以逗号分隔的链接列表中。现在,我的术语模型没有permalink字段,但它从我的视图中到达那里,并被传递到模板。permalink值在模板中看起来很好,但不会加载到我的模板标记中。

    为了说明这一点,我从代码中得到了一些信息。下面是我的自定义模板标记taxonomy_list:

    from django import template
    from juice.taxonomy.models import Term
    from juice.news.models import Post
    
    register = template.Library()
    
    @register.tag
    def taxonomy_list(parser, token):
        tag_name, terms = token.split_contents()
        return TaxonomyNode(terms)
    
    class TaxonomyNode(template.Node):
        def __init__(self, terms):
            self.terms = template.Variable(terms)
        def render(self, context):
            terms = self.terms.resolve(context)
            links = []
    
            for term in terms.all():
                links.append('<a href="%s">%s</a>' % (term.permalink, term.name))
    
            return ", ".join(links)
    

    # single post view
    def single(request, post_slug):
        p = Post.objects.get(slug=post_slug)
        p.tags = p.terms.filter(taxonomy='tag')
        p.categories = p.terms.filter(taxonomy='category')
    
        # set the permalinks
        for c in p.categories:
            c.permalink = make_permalink(c)
        for t in p.tags:
            t.permalink = make_permalink(t)
    
        return render_to_response('news-single.html', {'post': p})
    

    这就是我在模板中所做的,来说明访问类别的两种方法:

    Method1: {% taxonomy_list post.categories %}
    Method2: {% for c in post.categories %}{{c.slug}} ({{c.permalink}}),{% endfor %}
    

    有趣的是2号方法工作得很好,但1号方法说my.permalink字段未定义,这可能意味着变量解析没有按我的预期完成,因为“额外”permalink字段被省略了。

    我认为变量可能无法识别字段,因为它没有在模型中定义,所以我尝试在模型中为它分配一个“临时”值,但这也没有帮助。方法1在链接中包含“临时”,而方法2工作正常。

    有什么想法吗?

    谢谢!

    1 回复  |  直到 14 年前
        1
  •  2
  •   Daniel Roseman    14 年前

    这其实不是一个分辨率可变的问题。问题是如何从Post对象获取术语。

    当在模板标记中 for term in terms.all() ,和 all 告诉Django重新计算queryset,这意味着再次查询数据库。因此,经过仔细注释的术语将使用数据库中的新对象进行刷新,并且 permalink 属性被重写。

    如果你把这个 -所以你只是 for term in terms: . 这将重用现有对象。