Remote model in Flask-Admin
The task is to show a model from another application in Flask-Admin.
A way to do it is to overwrite BaseModelView
and get the data through HTTP request.
Here is a simple example for a sortable list with a pagination.
Suppose there is a model in app2
class MyModel(DynamicDocument):
name = StringField()
created_time = DateTimeField(default=datetime.utcnow)
To get the list of models it will require a endpoint
@api_blueprint.route('/mymodels', methods=['POST'])
def list_mymodels():
data = request.get_json()
objects = MyModel.objects
count = objects.count()
sort_field = data.get('sort_field')
sort_desc = data.get('sort_desc')
page = data.get('page', 0)
page_size = data.get('page_size', 10)
if sort_field:
if sort_desc:
sort_field = '-' + sort_field
objects = objects.order_by(sort_field)
objects = objects[page * page_size : (page + 1) * page_size]
return jsonify(count=count, objects=[{
'id': str(obj.id),
'name': obj.name,
'created_time': http_date(obj.created_time),
} for obj in objects])
To request this data from Flask-Admin in app1
class DictModel(object):
def __init__(self, **entries):
self.__dict__.update(entries)
def __getitem__(self, item):
return self.__dict__.get(item)
class RestModelView(BaseModelView):
can_edit = False
can_create = False
can_delete = False
can_view_details = False
page_size = 20
def get_pk_value(self, model):
return model['id']
def get_list(self, page, sort_field, sort_desc, search, filters, page_size=None):
if not page_size:
page_size = self.page_size
response = requests.post(
self.model.endpoint,
data=json.dumps(dict(
page=page,
sort_field=sort_field,
sort_desc=sort_desc,
search=search,
filters=filters,
page_size=page_size
)),
headers={'Content-Type': 'application/json'}).json()
return response['count'], [self.model(**d) for d in response['objects']]
def scaffold_form(self):
return Form
class MyModelView(RestModelView):
def scaffold_list_columns(self):
return ['name', 'created_time']
def scaffold_sortable_columns(self):
return {'Created time': 'created_time'}
class MyModel(DictModel):
endpoint = 'http://app2:8080/mymodels'
admin.add_view(MyModelView(MyModel))