Flask WTForms SelectField Создание выбора из данных API - PullRequest
1 голос
/ 27 мая 2019

Я извлекаю информацию из 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» моему маршруту в виде переменной 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>

Что мне нужно сделать, так это использовать «Item» из «Unit» с идентификатором, совпадающим с id из переменной url, в качестве выбора для поля выбора.

Я не могу найти способ добавить варианты в поле на уровне шаблона, что было бы моим предпочтительным методом. Что-то вроде:

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

Я рассчитывал найти подобное решение, потому что я больше всего знаком с Jinja2.

Поскольку я не могу найти способ заставить это работать, я пытался выяснить, как создать варианты выбора поля выбора в маршруте. Это сообщение было полезно: Динамический выбор WTForms Flask SelectField

однако мои данные структурированы по-другому, потому что есть дополнительный вложенный слой.

Я думаю, что я понимаю это правильно, перебирая «Единицы», чтобы найти единицу с идентификатором, совпадающим с моей переменной, и назначая эту «Единицу» переменной. Затем я могу сделать то же самое, что и в посте, связанном выше, используя значение ключа для цикла (я не знаю, как это называется или как это работает, поэтому я не могу искать, как это работает):

@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: неверный литерал для int () с основанием 10:'

очевидно, ключ должен быть целым числом, а не строкой. Проблема заключается в том, что описание и идентификатор из данных API являются строками, а идентификатор представляет собой комбинацию букв / цифр, которую нельзя преобразовать в целое число.

Мне нужно, чтобы описание было отображаемым текстом для опции поля выбора, и мне нужно, чтобы значение было строкой идентификатора.

что я могу использовать в качестве ключа, если у меня нет целочисленного идентификатора? как имя и значение применяются к параметрам поля выбора, если я не могу использовать строку идентификатора в качестве ключа? Я предполагаю, что ключ будет значением поля выбора.

** ОБНОВЛЕНИЕ: я заменил элемент ['ID'] на номер '1':

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

и теперь страница отображается, и поле выбора работает, но все значения поля выбора установлены в '1':

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

Значение должно быть идентификатором элемента из данных API, которое выглядит следующим образом:

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

но невозможно использовать строку в качестве значения. Любой совет будет оценен.

1 Ответ

0 голосов
/ 27 мая 2019

Я форсировал значение int, установив coerce на int в настройках моего поля. По умолчанию для coerce используется Unicode. Однажды я изменил, чтобы поле заполнялось так, как положено.

...