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.