“模板语法错误:过滤器无效:”;基于 django 文档的自定义 django 模板过滤器损坏,但模板标签有效

Posted

技术标签:

【中文标题】“模板语法错误:过滤器无效:”;基于 django 文档的自定义 django 模板过滤器损坏,但模板标签有效【英文标题】:"TemplateSyntaxError: Invalid filter:"; custom django template filter based on django docs broken, but template tags working 【发布时间】:2015-11-08 18:07:51 【问题描述】:

我有一个基于 https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/ 的 django 文档的模板过滤器。在我的一生中,我看不出我的用法和他们的用法有什么不同,而且我正在慢慢发疯。我在论坛上有一个工作标签:

myproject/index/templatetags/add_get_parameter.py:

from django.template import Library, Node, resolve_variable

register = Library()

class AddGetParameter(Node):
    def __init__(self, values):
        self.values = values

    def render(self, context):
        req = resolve_variable('request', context)
        params = req.GET.copy()
        for key, value in self.values.items():
            params[key] = value.resolve(context)
        return '?%s' %  params.urlencode()

@register.tag
def add_get(parser, token):
    pairs = token.split_contents()[1:]
    values = 

    for pair in pairs:
        s = pair.split('=', 1)
        values[s[0]] = parser.compile_filter(s[1])
    return AddGetParameter(values)

第 8-9 行的 add_get 有效,而第 4 行的 shorten_title 无效:

myproject/templates/index/silo.html

% load bootstrap add_get_parameter extras %



 ...other stuff...

% for article in articles %
        <div  class="col-md-4 article-link">
            <div class="panel panel-default hover">
                <div class="panel-heading"><h4 class="url-link"> article.title|shorten_title </h4></div>
                <div class="panel-body">
                    <p>&nbsp;<span class="url-text"> article.url </span></p>
                    <a href="% url 'index:edit-article' article.id %"><div class="article_button">Edit</div></a>
                    <a href="% add_get archive=article.id %"><div class="article_button"><p>Archive</p></div></a>
                    <a href="% add_get delete=article.id %"><div class="article_button">Delete</div></a>
                    <div style="margin-top:8px;">
                        % for tag in article.tags.all %
                            <p class="tag"> tag.name </p>
                        % endfor %
                    </div>
                </div>
              </div>
    </div>
% endfor %

这是恶棍:

from django.template import Library

register = Library()

@register.filter
def shorten_title(title):
    length = len(title)
    new = title
    if length > 65:
        new = title[0:65] + "..."
    return new
register.filter('shorten_title', shorten_title)

他太粗鲁了,我双重注册了他,只是为了看看会发生什么(他没有注册一次或之后注册,也没有注册两次)。

article.title 有效,但 article.title|shorten_title 打破页面:

django.template.base.TemplateSyntaxError
TemplateSyntaxError: Invalid filter: 'shorten_title'

'Index' 肯定已注册并正常工作,当我从该 article.title 标记中删除过滤器时,该页面正常工作。

通常当我遇到一个顽固的错误时,我会遗漏一些小东西,但逐字逐句地遵循文档让我感到困惑(我之前写过几个有效的过滤器)。这个过滤器是坏的,还是我的页面中可能有其他东西导致了这个问题?谢谢

【问题讨论】:

那么shorten_title 代码在哪里?什么文件?您是否在模板中导入该文件? (另请注意,您不应同时使用装饰器和直接register.filter(..) 调用:选择其中一个。) 短标题在 extras.py 中。我从字面上将代码从那里剪切并粘贴到一个没有标签的新文件中(只有这个过滤器),现在它可以工作了。是否可能是您必须删除所有 pyc 的那些奇怪的 pyc 事情之一,或者模板标签和过滤器不应该在同一个文件中?两次遵循 django 示例,一天有效,一天无效 【参考方案1】:

您需要确保在渲染模板之前使用register.filter('shorten_title', shorten_title) 导入文件。由于该调用发生在任何函数之外,它在您导入模块时运行。这具有注册它的副作用,以便之后它可以在您的模板中使用。

【讨论】:

在哪里?我目前拥有上面列出的它,register.filter('shorten_title', shorten_title) 就在同一文件中的过滤器下方(index/templatetags/extras.py) 是的,没错。您只需要在使用过滤器之前导入具有该行的整个模块。如果该文件从未被导入,则过滤器永远不会被注册。 在视图中?喜欢from index.templatetags import extras?我在 .html 文件中的模板中加载附加内容 我认为是在视图或模板中。现在我看到% load bootstrap add_get_parameter extras %,一些非常相似的东西应该适用于shorter_title。我不太确定 Django 中最好的方法是什么,因为我是根据对 Flask 的类似经验来回答这个问题的。 django 总是有一些东西。认为是时候学习 Rails 了

以上是关于“模板语法错误:过滤器无效:”;基于 django 文档的自定义 django 模板过滤器损坏,但模板标签有效的主要内容,如果未能解决你的问题,请参考以下文章

Django:基于注释进行注释

基于python或django的workflow engine

Django第一课 基于Django图书借阅管理网站平台

Django第一课 基于Django图书借阅管理网站平台

Django第一课 基于Django超市订单管理系统开发

Django第一课 基于Django超市订单管理系统开发