Django custom template tag with 'parser.compile_filter(tokens[2])' doesn't work
I tried to implement the solution proposed by T. Stone on my question "how-do-i-pass-a-lot-of-parameters-to-views-in-django" ([link text][1]).
I can't manage to get any result. It's difficult to find information about thecompile_filter()
, but as far as I understand cls(queryset=parser.compile_filter(tokens[2]), template=template)
should render the template with the 'variable' tokens[2]. But that doesn't seems to work.
Here is the code of my implementation:
models.py:class SalesRecord(models.Model):
name = models.CharField(max_length=100)
month = models.CharField(max_length=10)
revenue = models.IntegerField()
def __unicode__(self):
return self.name + " - " + self.month + " - " + str(self.revenue)
views.py:
def test(request, *args, **kwargs):
name = 'John'
monthly_sales_qs = SalesRecord.objects.filter(name=name)
print monthly_sales_qs
return render_to_response('test.html', locals())
mytags.py:
class DataForTag(template.Node):
@classmethod
def handle_token(cls, parser, token, template):
tokens = token.contents.split()
if tokens[1] != 'for':
raise template.TemplateSyntaxError("First argument in %r must be 'for'" % tokens[0])
if len(tokens) == 3:
return cls(queryset=parser.compile_filter(tokens[2]), template=template)
else:
raise template.TemplateSyntaxError("%r tag requires 2 arguments" % tokens[0])
def __init__(self, queryset=None, template=None):
self.queryset = queryset
self.template = template
def render(self, context):
return render_to_string(self.template, {'queryset':self.queryset})
@register.tag
def render_data_table(parser, token):
return DataForTag.handle_token(parser, token, 'testtable.html')
test.html:
{% load mytags %}
{% render_data_table for monthly_sales_qs %}
testtable.html:开发者_StackOverflow中文版
<table class="tabledata">
<tr>
{% for m in queryset.month %}
<td>queryset.revenue</td>
{% endfor %}
</tr>
</table>
The template just returns an empty page. It seems to me that the queryset is empty. Does someone have an idea what I'm doing wrong? (probably some beginners stupidity ;)
Mark...
Couple of things: I was in a rush the other day when I posted that code for you. Within the render
method variables need to be resolved as such...
def render(self, context):
qs = self.queryset.resolve(context)
return render_to_string(self.template, { 'queryset': qs } )
Also, in your template, this is wrong:
{% for m in queryset.month %}
<td>queryset.revenue</td>
{% endfor %}
First, variables need to be wrapped in {{ }}'s like {{ queryset.revenue }}
and second you're not doing anything with the m
value so having the for
loop is pointless.
Lastly, the pattern I showed you in the answer I found in the django.contrib.comments
app. If you want to follow some existing/working examples I'd recommend checking out the comments template tags. Lots of great ideas in that app.
精彩评论