1

I am pulling information from an api that is delivered like this:

{
  "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"
         }
       ]
     }
    ]
  }
}

I am providing a wtform with a select field:

forms.py

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

I am passing the id of the "Unit.id" to my route as a url variable:

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)

and in my view I am printing the form:

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

What I need to do is use the 'Item's, from the 'Unit' with the ID that matches the id from the url variable, as the choices for the select field.

I cannot seam to find a way to add choices to the field at the template level, which would be my preferred method. Something like:

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

I was banking on finding a solution like this, because I am most familiar with Jinja2.

Since I cannot find a way to make that work, I have been trying to figure out how to create the selectfield choices in the route. This posts was helpful: Dynamic choices WTForms Flask SelectField

however my data is structured differently because there is an extra nested layer.

I think I am getting it right, by looping through the 'Units' to find the one with an id matching my variable, and assigning that 'Unit' to a variable. Then I can do like on the post linked above, using a key value for loop (I do not know what this is called or how it works so I am not able to search for how it works):

@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)

I am pretty sure this is going to work, but I am receiving an error 'alueError: invalid literal for int() with base 10:'

obviously the key needs to be an integer, not a string. The problem is that both the description and ID from the api data are strings, and the id is a letter/number combo that can't be converted to an integer.

I need the description to be the display text for the select field option, and I need the value to be the ID string.

what can I use as the key if I don't have an integer ID? how do the name and value apply to the select field options if I can't use the ID string as the key? I am assuming the key will be the select field value.

**UPDATE: I replaced item['ID'] with the number '1':

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

and now the page is rendering, and the select field is working, but all of the select field values are set to '1':

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

The value needs to be the ID of the item form the api data, and that looks like:

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

but it doesn't seam to be possible to use a string as the value. any advice would be appreciated.

1 Answer 1

0

I was forcing an int value by setting coerce to int in my field settings. The default for coerce is unicode. Once I changed that the field populated as it is supposed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.