Item.bind for a foreign key relationship?

How can I use the item.bind[] functionality for an input box if the input is describing a particular field on a foreign table that the item has a foreign-key relationship with?

example:
item is a User.
the user has a field called ‘type’, which links to a UserType table.
the UserType table has a field called ‘text’, which is what I show in a dropdown on a particular form.
I want to choose a different dropdown and have the UserType updated, using the item.bind shorthand.

Ok IDK if this is the shortest way to do this, but I was able to accomplish this by leaving the ‘Items’ field in the WYSIWYG empty and instead setting the item values via the __init__ method of the form:
image

As mentioned here, if you assign the items property to a list of two-tuples, you can specify that the display-text is different from the actual value passed to the back-end.

1 Like

You might like a for loop here. Something like:

 ... = [  ( display_name, app_tables.usertypes.get(text=display_name) )
  for display_name in [ 'Active', 'Associate', 'Interim', 'Applicant' ] 
]
2 Likes

There is a how-to guide for doing this in the Anvil docs:

DropDowns and Data Tables

3 Likes

Ok so the solution is to leave the ‘Items’ field in the WYSIWYG empty and instead set the item values via the __init__ method of the form like this:
self.input_usertype.items = [(t['text'], t) for t in app_tables.usertypes.search()]

This works, but… careful: you are executing 4 round trips.

It works while prototyping, but in cases like this is always good practice to run that very code on the server side and then return one single object in one call. Something like this:

self.input_usertype.items = anvil.server.call('get_usertypes')

And on the server side:

def get_usertypes():
  return [  ( display_name, app_tables.usertypes.get(text=display_name) )
  for display_name in [ 'Active', 'Associate', 'Interim', 'Applicant' ] 
]

I usually make sure I make only one round trip by creating one function that returns everything the form needs in one single dictionary. Something like this:

def get_form_stuff():
  return {
    'usertypes': [(display_name, app_tables.usertypes.get(text=display_name) )
                   for display_name in [ 'Active', 'Associate', 'Interim', 'Applicant']],
    'something_else': [...]
  }
2 Likes