2013-06-04 37 views
-1

我有一个模型树,并使用模型递归渲染自己使用自定义模板标记。Django:自定义模板标记递归调用

每个Widget模型都拥有模板和上下文数据,并且可以自行渲染。 控件可能有子控件模型,子控件将首先渲染,父控件可以组装它们。

而模板使用自定义标签。

型号代码

class Widget(models.Model): 
slug = models.SlugField(max_length=255, unique=True) 
title = models.CharField(max_length=50, blank=True) 
sub_title = models.CharField(max_length=50, blank=True) 
parent = models.ForeignKey('self', null=True, blank=True, 
     related_name='widget', verbose_name=u'') 
position = models.PositiveSmallIntegerField(default=1); 
links = models.ManyToManyField(Link) 
template = models.FilePathField(
      path='templates/widgets/', 
      match='.*.html$', choices=WIDGETS_TEMPLATE, blank=True) 
content = models.TextField(default="{}") 

objects = WidgetManager() 

def __unicode__(self): 
    return self.title 

def get_template(self): 
    return path.join(settings.PROJECT_PATH, self.template) 

def get_content(self): 
    return self.content 

def get_template_slug(self): 
    return self.template.split('/')[-1][:-5] 

def get_content_json(self): 
    # return self.encodeContent() 
    return json.loads(self.content) 

标签代码

class WidgetNode(template.Node): 

def __init__(self, position): 
    self.template = 'widgets/index-cools-subs.html' 
    # print template.Variable(self.positon) 
    self.position = template.Variable(self.position) 

def render(self, context): 
    widgets = context['widgets'] 
    attrs = {} 
    for widget in widgets: 
     if widget.position == self.position: 
      children = Widget.objects.filter(parent=widget) 
      if children: 
       attrs['widgets'] = [child for child in children] 
      else: 
       attrs = widget.get_content_json() 
      self.template = widget.get_template() 
    return render_to_string(self.template, attrs) 

def widget(parser, token): 
try: 
    tag_name, position = token.split_contents() 
except ValueError: 
    msg = 'widget %s value error.' % token 
    raise template.TemplateSyntaxError(msg) 
return WidgetNode(position) 

模板代码

<div class="section" name="subs" fd="index"> 
{% for widget in widgets %} 
    {% widget widget.position %} 
{% endfor %} 
</div> 

我有两个ISSU es:

  • template.Variable得到null,可能是逻辑错误或其他。
  • 定制标记工作在for循环中没有意义,它不会在循环中调用。

任何意见是非常感谢。

谢谢。

+0

实践证明自定义标签是递归调用是可行的。 – caihuo

回答

1

的Django只执行__init__当“建筑”的模板,渲染时只有render()被调用。因此,您需要使用模板变量进行摆弄,当您执行类似self.position = template.Variable(self.position)的操作时,您只告诉Django self.position是模板上下文中定义的变量,但不是其值;得到你需要的值resolve it when rendering

def render(self, context): 
    position = self.position.resolve(context) 
    # do something with position... 
+0

感谢Bernhard,它工作。 – caihuo

+0

你可以接受答案:) –