【问题标题】:Flask WTForms SelectField Create choices from api dataFlask WTForms SelectField 从 api 数据创建选择
【发布时间】:2019-10-12 15:00:25
【问题描述】:

我从这样传递的 api 中提取信息:

{
  "Location": {
    "Units": [
     {
       "id": 1,
       "Item": [
         {
           "Description": "some string value",
           "ID": "some string value"
         },
         {
           "Description": "some string value",
           "ID": "some string value"
         },
         {
           "Description": "some string value",
           "ID": "some string value"
         }
       ]
     },
     {
       "id": 2,
       "Item": [
         {
           "Description": "some string value",
           "ID": "some string value"
         },
         {
           "Description": "some string value",
           "ID": "some string value"
         },
         {
           "Description": "some string value",
           "ID": "some string value"
         }
       ]
     }
    ]
  }
}

我正在提供一个带有选择字段的 wtform:

forms.py

class ReserveForm(Form):
  item = SelectField(
    'Item',
    choices=[],
    coerce=int
  )

我将“Unit.id”的 id 作为 url 变量传递给我的路由:

app.py

@app.route('/reserve/<id>')
def reserve(id):
  data = *my api data in json format*
  form = ReserveForm()
  return render_template('reserve.html', data=data, form=form)

在我看来,我正在打印表单:

<form action="" method="POST">
  {{ form.hidden_tag() }}
  {{ form.item.label() }}
  {{ form.item() }}
</form>

我需要做的是使用 ID 与 url 变量中的 ID 匹配的“单元”中的“项目”作为选择字段的选项。

我无法找到在模板级别向字段添加选项的方法,这将是我的首选方法。比如:

<form action="" method="POST">
  {{ form.hidden_tag() }}
  {{ form.item.label() }}
  {{ form.item(choices=[data.Location.Unit[specific-ID].item]) }}
</form>

我希望找到这样的解决方案,因为我最熟悉 Jinja2。

由于我找不到实现该功能的方法,因此我一直在尝试弄清楚如何在路线中创建选择字段选项。这篇文章很有帮助:Dynamic choices WTForms Flask SelectField

但是我的数据结构不同,因为有一个额外的嵌套层。

我认为我做对了,循环遍历“Units”以找到 ID 与我的变量匹配的那个,并将该“Unit”分配给一个变量。然后我可以像上面链接的帖子一样,使用循环的键值(我不知道这叫什么或它是如何工作的,所以我无法搜索它是如何工作的):

@app.route('/reserve/<id>')
def reserve(id):
  data = *my api data in json format*
  for item in data['Location']['Unit']:
    if item['ID'] == id:
      unit = item
  items = [(item['ID'], item['Description']) for item in unit['Item']]
  form = ReserveForm()
  form.item.choices = items

  return render_template('reserve.html', data=data, form=form)

我很确定这会起作用,但我收到一个错误'alueError: invalid literal for int() with base 10:'

显然,键必须是整数,而不是字符串。问题是api数据中的description和id都是字符串,id是字母/数字组合,不能转换成整数。

我需要将描述作为选择字段选项的显示文本,并且我需要将值作为 ID 字符串。

如果我没有整数 ID,我可以使用什么作为键?如果我不能使用 ID 字符串作为键,名称和值如何应用于选择字段选项?我假设键将是选择字段值。

**更新:我将 item['ID'] 替换为数字“1”:

items = [(1, item['Description']) for item in unit['Item']]

现在页面正在渲染,选择字段正在工作,但所有选择字段的值都设置为“1”:

<option value="1">item name from api data</option>

该值需要是 api 数据中项目的 ID,如下所示:

'ID': 'babb87d5-323f-4d56-9ed0-e2b643a78936'

但是不可能使用字符串作为值。任何建议将不胜感激。

【问题讨论】:

    标签: python flask wtforms


    【解决方案1】:

    我通过在我的字段设置中将 coerce 设置为 int 来强制一个 int 值。强制的默认值是 unicode。一旦我更改了按预期填充的字段。

    【讨论】:

      猜你喜欢
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 2016-09-10
      • 2021-05-15
      • 2016-07-10
      • 2017-05-16
      • 2012-08-23
      相关资源
      最近更新 更多