Pergunta

I have a model tree, and use model to recursive render by itself using custom template tag.

Every Widget model own template and context data, and can be rendered by itself. Widget maybe have child widget model, child widget will be rendered first, parent widget can assemble them.

And template use custom tag.

Model code

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)

Tag code

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)

Template code

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

I have two issues:

  • template.Variable gets null, maybe logic error or others.
  • custom tag work not make sense in for loop, it not be called in loop.

Any advice is much appreciated.

Thanks.

Foi útil?

Solução

Django only executes the __init__ when "building" the template, when rendering only render() is called. Therefore you need this fiddling using template variables, when doing something like self.position = template.Variable(self.position) you tell Django only that self.position is a variable defined in the template's context, but not its value; to get the value you need to resolve it when rendering:

def render(self, context):
    position = self.position.resolve(context)
    # do something with position...
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top