I'm building a Flask-Admin app that uses a REST API as its backend database, which I've implemented as my own BaseModelView. I've got it working with a custom model, and implemented all the functions to edit and save the model.
However I have one field, User, which needs to search another REST API endpoint for a User ID based on name/email, and as the list of users is expected to become quite large I want that field to be an AJAX lookup as I've seen in the SQLAlchemy example looking up a foreign key via Select2/Ajax.
As I need my own Ajax lookup, from following the docs and reading through the code, I'm struggling to find a working example of how to implement it myself and was wondering if anyone can direct me.
I've tried implementing an AjaxSelectField and using the form_ajax_refs property of BaseModelView to override the User field of the form (created in the scaffold_form method) without success.
Does anyone have an example of how I can put a custom Select2 Ajax lookup field, that looks up data from a REST API, on my model form so I can search for a User ID to assign to the model when I create/edit a model?
Figured it out finally, you have to add 2 things to your BaseModelView to do this:
In your BaseModelView class - Add an AjaxSelectField to your form with a custom model form:
def scaffold_form(self):
class AccountForm(Form):
owner = AjaxSelectField(UserAjaxModelLoader('owner'),
label='Owner', blank_text="Select User...")
return AccountForm
Then add a reference to your form_ajax_refs
field:
form_ajax_refs = {
'owner': UserAjaxModelLoader('owner')
}
Finally the implementation of the UserAjaxModelLoader
class which provides the AJAX endpoint and strings it all together:
from flask_admin.model.ajax import AjaxModelLoader, DEFAULT_PAGE_SIZE
class UserAjaxModelLoader(AjaxModelLoader):
def __init__(self, name, **options):
super(UserAjaxModelLoader, self).__init__(name, options)
def format(self, model):
if model:
return (model.uid, model.email)
return None
def get_one(self, pk):
return auth.get_user(pk)
def get_list(self, query, offset=0, limit=DEFAULT_PAGE_SIZE):
# Put your code to search REST API for users here
return users