2010-04-12 1 views
4

Пытается решить проблему с templatetags.Для переменной цикла, используемой в templatetag?

У меня есть два templatetags:

@register.inclusion_tag('directory/_alphabet.html') 
def alphabet_list(names): 
    """ Return a list of letters that last names start with. """ 
    return { 'letters': [name.last_name[0] for name in names] } 

class NameNode(template.Node): 
    def __init__(self, letter, var_name): 
     self.letter = letter 
     self.var_name = var_name 

    def render(self, context): 
     context[self.var_name] = Person.objects.get_active().filter(
      last_name__istartswith=self.letter) 
     return '' 

@register.tag 
def get_names(parser, token): 
    try: 
     tag_name, arg = token.contents.split(None, 1) 
    except ValueError: 
     raise template.TemplateSyntaxError, "%r tag requires arguments" % \ 
       token.contents.split()[0] 
    m = re.search(r'for (.*?) as (\w+)', arg) 
    if not m: 
     raise template.TemplateSyntaxError, "%r tag had invalid arguments" % \ 
       tag_name 
    letter, var_name = m.groups() 
    return NameNode(letter, var_name) 

И я хочу, чтобы использовать их как так:

{% for letter in letters %} 
<h2>{{ letter }}</h2> 
{% get_names for letter as names %} 
<ul> 
    {% for name in names %} 
    <li>{{ name }}</li> 
    {% endfor %} 
</ul> 
{% endfor %} 

Но «буква» отправляется как слово «буква», а не как какой-то буквы в переменная должна содержать. Есть ли способ обойти это или что-то, что мне не хватает (или, еще лучше, пакет, который уже делает это)?

ответ

4

Вы получаете строку "letter", потому что это то, что анализатор шаблонов читает из вашего источника шаблона. Если вы хотите получить доступ к значению этой переменной, вы должны пометить ее как шаблонную переменную в NameNode.__init__ и решить, используя контекст в render.

следующим образом:

class NameNode(template.Node): 
    def __init__(self, letter, var_name): 
     self.letter = template.Variable(letter) 
     self.var_name = var_name 

    def render(self, context): 
     try: 
      context[self.var_name] = Person.objects.get_active().filter(
       last_name__istartswith=self.letter.resolve(context)) 
     except template.VariableDoesNotExist: 
      pass 
     return '' 

Это объясняется в документации here.

+0

Спасибо. Я прочитал эти документы, но пропустил часть .resolve(). – kennethlove