Opened 10 years ago

Closed 10 years ago

Last modified 8 years ago

#475 closed defect (invalid)

Recursive function calling not working properly in template tags

Reported by: espen@… Owned by: adrian
Component: Template system Version:
Severity: major Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

In templatetags/blog_tags.py:

class GetCategoriesList(template.Node):
  def render(self, context):
    res = "<ul><!-- render called -->\n"
    # getting all elements that got no parent
    base_list = categories.get_list(parent__isnull=True) 
    
    for base_element in base_list:
      res += self.__get_childrens(res, base_element)
    
    res += '</ul><!-- end of render -->\n'
    return res
  
  def __get_childrens(self, res, parent):
    res += '<!-- %s (inside __get_childrens) -->\n' % parent.name
    return res

What i should get:

<ul><!-- start get_first -->
<!-- Geek stuff -->
<!-- Left to die -->
<!-- Personal -->
<!-- School -->
</ul><!-- end get_first -->

The output i get when using my custom template tag:

<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<ul><!-- start get_first -->

<ul><!-- start get_first -->
<!-- Geek stuff -->
<!-- Left to die -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<!-- Left to die -->
<!-- Personal -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->

<!-- Left to die -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<ul><!-- start get_first -->
<ul><!-- start get_first -->
<!-- Geek stuff -->
<!-- Left to die -->
<!-- Personal -->
<!-- School -->
</ul><!-- end get_first -->

Change History (4)

comment:1 Changed 10 years ago by espen@…

Seems like I've changed the comments (and not the code) a little between copying the code and output into the ticket, sorry for that.

comment:2 Changed 10 years ago by anonymous

  • Resolution set to invalid
  • Status changed from new to closed

I don't think that it is a template tag problem. I can't test it right now but after reading over the code it looks like this should fix it (see the get_childrens method):

class GetCategoriesList(template.Node):
  def render(self, context):
    res = "<ul><!-- render called -->\n"
    # getting all elements that got no parent
    base_list = categories.get_list(parent__isnull=True) 
    
    for base_element in base_list:
      res += self.__get_childrens(base_element)
    
    res += '</ul><!-- end of render -->\n'
    return res

  def __get_childrens(self, parent):
    return  '<!-- %s (inside __get_childrens) -->\n' % parent.name

comment:3 Changed 10 years ago by Espen Grindhaug <espen@…>

Thanks anonymous, i got it to work, by changing the += to a = when i called self.get_childrens function. As Linus' law sais "given enough eyeballs, all bugs are shallow", and thanks again.

comment:4 Changed 10 years ago by Simon Willison

Just as a general Python note, rather than gluing strings together with the += operator (which creates a new duplicated string in memory every time you use it) a better idiom is to do this:

res = []
res.append('Some HTML')
res.append('Some more HTML')
...
return ''.join(res)
Note: See TracTickets for help on using tickets.
Back to Top