I'm looking to have a form that has a field type multiselect using deform (as into this example http://deformdemo.repoze.org/select2_with_multiple/) but with choices coming from a remote data source (json call).
What will be the best way to implement it - is it possible with deform2 or should I just fall back to jquery etc.
thanks!
It is definitely easier to populate the selection values on the server-side You can do this using colander deferred to set the values
for the choice field:
@colander.deferred
def deferred_choices_widget(node, kw):
choices = kw.get('choices')
return deform.widget.SelectWidget(values=choices)
@colander.deferred
def deferred_default(node, kw):
return kw['default']
class Schema(colander.Schema):
pepper = colander.SchemaNode(
colander.String(),
default=deferred_default,
widget=deferred_choices_widget,
)
def view(request):
# choices = (
# ('', '- Select -'),
# ('habanero', 'Habanero'),
# ('jalapeno', 'Jalapeno'),
# ('chipotle', 'Chipotle')
# )
choices = load_data_from_some_api()
schema = Schema().bind(choices=choices, default='jalapeno')
form = deform.Form(schema, buttons=('submit',))
return self.render_form(form)
However, to make it fast, you probably want to have some sort of cache. Usually a good pattern is
Have a scheduled task (Celery) to fetch values from the API e.g. once in 60 minutes and store them in database
Your view code doesn't perform any time expensive API calls, but always populates the values directly from the database