如何在 WTForms 中输入列表?

How to enter a list in WTForms?

我想做什么

我正在尝试在 Flask 中输入一个标签列表,这些标签应该可以作为列表通过,但我不知道如何在 Flask 中执行此操作,也找不到添加列表(字符串)的文档在 flask_wtf。有没有人有这方面的经验?

理想情况下,我希望在您输入标签后可以有选择地删除它们。以便您可以进入。

问题

到目前为止,我的表单是静态的。你输入东西,点击提交,它被处理成 .json。标签列表是我无法弄清楚的最后一个元素。我什至不知道烧瓶是否可以做到这一点。

关于我如何设想进入过程的一个小演示:

我是如何设想进入流程的:

  1. 显示当前标签和用于添加新标签的输入字段。
    [Tag1](x) | [Tag2](x)

    Enter new Tag: [______] (add)
  1. 点击(添加)
    [Tag1](x) | [Tag2](x)

    Enter new Tag: [Tag3__]  (add)
  1. 添加了新标签
    [Tag1](x) | [Tag2](x) | [Tag3](x) 

    Enter new Tag: [______]

我是如何设想删除过程的:

  1. 点击标签一侧的 (x) 应该会杀死它。
    [Tag1](x) | [Tag2](x) | [Tag3](x) 
  1. 在 Tag2 上点击 (x)。结果:
    [Tag1](x) | [Tag3](x)

删除有点锦上添花,可能会完成,一旦我有了可以编辑的列表,但要做到这一点似乎很难。 我在这里不知所措。

我基本上想知道是否可以输入一般列表,因为似乎没有关于该主题的文档。

我发现了一个 viable solution in this 2015 book,其中正在为 Flask 构建标记系统作为博客构建练习的一部分。

它基于 Flask_SQLAlchemy

因此,可以使用 WTForms / Flask 通过将项目提交到数据库来输入列表,例如FieldList 和在标记系统的用例中,从数据库中读回它们以在 UI.

中呈现它们

但是,如果您不想处理 O'Rielly 的付费专区(抱歉,我无法在此处 post 受版权保护 material)并且您想要的只是一个解决方案添加标签,查看 Sean Coker 的 taggle.js。它不是烧瓶,而是 javascript,但它可以完成工作。

您的描述不是很清楚(Tag1 是 JSON 中的键还是 Tag 是键,1 是索引?)

但我最近遇到了类似的问题,我想在 JSON 中提交一个基本的 list 并让 WTForms 正确处理它。

例如,这个:

{
    "name": "John",
    "tags": ["code", "python", "flask", "wtforms"]
}

所以,我不得不重写 FieldList 的工作方式,因为出于某种原因,WTForms 需要 list 作为 "tags-1=XXX,tags-2=xxx"

from wtforms import FieldList
class JSONFieldList(FieldList):
    def process(self, formdata, data=None):
        self.entries = []
        if data is None or not data:
            try:
                data = self.default()
            except TypeError:
                data = self.default

        self.object_data = data

        if formdata:
            for (index, obj_data) in enumerate(formdata.getlist(self.name)):
                self._add_entry(formdata, obj_data, index=index)
        else:
            for obj_data in data:
                self._add_entry(formdata, obj_data)

        while len(self.entries) < self.min_entries:
            self._add_entry(formdata)

    def _add_entry(self, formdata=None, data=None, index=None):
        assert not self.max_entries or len(self.entries) < self.max_entries, \
            'You cannot have more than max_entries entries in this FieldList'
        if index is None:
            index = self.last_index + 1
        self.last_index = index
        name = '%s-%d' % (self.short_name, index)
        id = '%s-%d' % (self.id, index)
        field = self.unbound_field.bind(form=None, name=name, id=id, prefix=self._prefix, _meta=self.meta,
                                        translations=self._translations)
        field.process(formdata, data)
        self.entries.append(field)
        return field

在 Flask 端处理表单:

from flask import request
from werkzeug.datastructures import ImmutableMultiDict

@app.route('/add', methods=['POST'])
def add():
    form = MyForm(ImmutableMultiDict(request.get_json())
    # process the form, form.tags.data is a list

和表格(注意JSONFieldList的使用):

class MonitorForm(BaseForm):
    name = StringField(validators=[validators.DataRequired(), validators.Length(min=3, max=5)], filters=[lambda x: x or None])
    tags = JSONFieldList(StringField(validators=[validators.DataRequired(), validators.Length(min=1, max=250)], filters=[lambda x: x or None]), validators=[Optional()])