如何使用 WTForms 绘制没有 id 属性的输入?

How to draw inputs without the id attribute using WTForms?

在我的 Flask 应用程序中,我必须在同一页面上多次绘制表单。这导致我在页面上有多个具有相同 id 的输入字段的问题。例如:

class ChannelForm(flask_wtf.Form):
     name = StringField('name')

连同此模板:

<form>
    {{ form.name }}
</form>
...
<form>
    {{ form.name }}
</form>

导致两个相同的输入元素id:

<input id="name" name="name" value="" type="text">

是否有官方方法来禁用添加 id 属性?

我认为您可以像这样将自定义 ID 传递给字段构造函数:

<form>
    {{ form.name(id_='yourId') }}
</form>
...
<form>
    {{ form.name(id_='yourId2') }}
</form>

快又脏:

我发现以下方法效果很好:我没有直接使用字段,而是将它们包装在 jinja 宏中:

{% macro render_field(field) %}
<label>
    <span>{{ _field.label.text }} </span>
    {{ field(id=False, **kwargs) }}
</label>
{% endmacro %}

可以这样使用:

{% from "_formhelpers.html" import render_field %}
{{ render_field(form.name) }}

这里的技巧是在渲染字段时传递id=False

使用元对象:

_Auto = object()
class NoIdAttributeMeta(DefaultMeta):
    """
    Surpresses rendering the `id' attribute.
    """

    def bind_field(self, form, unbound_field, options):
        """
        Raises TypeError in case 'id' is given as a positional arg when constructing a field.
        If this happens, make this code smarter or pass `id' as a keyword arg.
        """
        # we check `id' at rendering time and if it is still _Auto, do not render it
        unbound_field.kwargs.setdefault('id', _Auto)
        return super().bind_field(form, unbound_field, options)

    def render_field(self, field, render_kw):
        if field.id is _Auto:
            field.id = False
        return super().render_field(field, render_kw)

class MyForm(flask_wtf.Form):
    Meta = NoIdAttributeMeta

或务实:

您还可以为表单的每个实例添加不同的前缀,因此您将拥有唯一的 ID:

my_form = MyForm(prefix="form1")
    pass

您不需要 id=False,因为您已经可以在调用 render_field()

时设置 id
{% macro render_field(_field) %}
<label>
    <span>{{ _field.label.text }} </span>
    {{ _field(**kwargs) }}
</label>
{% endmacro %}

用法:

{{ render_field(field, id=False) }}

说明: 因为你有 ****kwargs**,所以你可以使 id=False,这样会更动态。您可以选择何时删除 ID。 希望这对那些用谷歌搜索过这个解决方案的人有所帮助