【问题标题】:template tag 'add' requires 2 arguments, 1 provided模板标签“添加”需要 2 个参数,提供 1 个
【发布时间】:2018-05-04 10:04:59
【问题描述】:

我之前使用过add,但这次却遇到了这个奇怪的错误:

django.template.exceptions.TemplateSyntaxError: add requires 2 arguments, 1 provided

使用以下代码:

{% render_field form.full_name type="hidden" class="form-control" \
   value=user.first_name|add:"something" %}

但是,如果我将 add 移动到 with,我不会收到错误消息:

{% with fullname=user.first_name|add:"something"%}
   {% render_field form.full_name type="hidden" class="form-control" \
      value=fullname %}
{% endwith %}

【问题讨论】:

    标签: django django-templates django-widget-tweaks


    【解决方案1】:

    所以看起来您正在使用来自https://github.com/jazzband/django-widget-tweaks/render_field 模板标签

    render_field 被实现为由包维护者实现的Advanced Custom Tag,遗憾的是它的参数列表中不支持过滤器。

    另一方面,simple_taginclusion_tag;由 Django 定义;确实支持其参数列表中的其他过滤器。

    我的意思是,如果它是 simple_taginclusion_tag,这将起作用 {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

    但是,如果my_tag 被注册为高级自定义标签;在参数中支持过滤器取决于实现。

    正如我从render_field 代码的实现中看到的那样;这是一个高级自定义标签,过滤器支持似乎被破坏了:

    @register.tag
    def render_field(parser, token):
        """
        Render a form field using given attribute-value pairs
    
        Takes form field as first argument and list of attribute-value pairs for
        all other arguments.  Attribute-value pairs should be in the form of
        attribute=value or attribute="a value" for assignment and attribute+=value
        or attribute+="value" for appending.
        """
        error_msg = '%r tag requires a form field followed by a list of attributes and values in the form attr="value"' % token.split_contents()[0]
        try:
            bits = token.split_contents()
            tag_name = bits[0]
            form_field = bits[1]
            attr_list = bits[2:]
        except ValueError:
            raise TemplateSyntaxError(error_msg)
    
        form_field = parser.compile_filter(form_field)
    
        set_attrs = []
        append_attrs = []
        for pair in attr_list:
            match = ATTRIBUTE_RE.match(pair)
            if not match:
                raise TemplateSyntaxError(error_msg + ": %s" % pair)
            dct = match.groupdict()
            attr, sign, value = \
                dct['attr'], dct['sign'], parser.compile_filter(dct['value'])
            if sign == "=":
                set_attrs.append((attr, value))
            else:
                append_attrs.append((attr, value))
    
        return FieldAttributeNode(form_field, set_attrs, append_attrs)
    

    具体来说; key=value 对存储在代码中的 attr_list 中,并针对 ATTRIBUTE_RE 正则表达式匹配运行

    然后过滤器使用parser.compile_filter(dct['value']) 运行,但是dct['value']'user.first_name|add:"' -> 文本"something" 在这里丢失了。我的猜测是ATTRIBUTE_RE 正则表达式需要改进以支持这一点。

    >>> ATTRIBUTE_RE.match('value=user.first_name|add:"something"')
    <_sre.SRE_Match object at 0x7f8617f5a160>
    >>> match.groupdict()
    {'attr': 'value', 'value': 'user.first_name|add:"', 'sign': '='}
    

    如您所见,value 键已损坏并且缺少您提供的全文;这会破坏下游的添加过滤器。

    这正是with 标签旨在解决的用例;因为它将过滤过程抽象到更高的级别;您可以将新变量很好地传递给您的自定义render_field 标签。

    参考资料:

    How to use a template filter on a custom template tag?

    https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#advanced-custom-template-tags

    【讨论】:

    • 感谢@rtindru 的详细解释!有道理
    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多