Django自定义模板标签使用'parser.compile_filter(tokens[2])'不工作

2 投票
1 回答
1830 浏览
提问于 2025-04-15 22:12

我试着按照T. Stone在我提问“如何在Django中传递很多参数给视图”时提出的解决方案来实现。
但是我没有得到任何结果。关于compile_filter()的信息很难找到,但据我理解,cls(queryset=parser.compile_filter(tokens[2]), template=template)应该用'tokens[2]'这个变量来渲染模板。但是这似乎没有效果。

这是我实现的代码:
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:

<table class="tabledata">
    <tr>
    {% for m in queryset.month %}
        <td>queryset.revenue</td>
     {% endfor %}
     </tr>
</table>

模板只返回了一个空白页面。看起来我的查询集是空的。
有没有人知道我哪里做错了?(可能是一些初学者的愚蠢错误;)

1 个回答

1

Mark...

有几件事要说:我前几天发给你的代码时有点匆忙。在render方法里,变量需要这样处理...

def render(self, context):
    qs = self.queryset.resolve(context)
    return render_to_string(self.template, { 'queryset': qs } )

另外,在你的模板里,这部分是错的:

{% for m in queryset.month %}
    <td>queryset.revenue</td>
 {% endfor %}

首先,变量需要用{{ }}包起来,比如{{ queryset.revenue }}。其次,你对m这个值没有做任何处理,所以用for循环是没有意义的。

最后,我在我找到的答案中展示的模式是来自django.contrib.comments这个应用。如果你想参考一些现成的、有效的例子,我建议你看看评论模板标签。在那个应用里有很多不错的想法。

撰写回答