Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-Admin: route to models view with filter applied

I have a model in Flask-Admin with filter (e.g. based on Foreign Key to other model).

I want to generate links from front-end to this model view in admin with filter value applied. I noticed that it adds ?flt0_0= to the url, so that the whole address looks kinda:

http:/.../admin/model_view_<my model>/?flt0_0=<filter value>

Which is the best way to generate routes like this?

like image 207
vdikan Avatar asked Mar 06 '16 21:03

vdikan


2 Answers

I prefer setting named_filter_urls=True on my base view to get rid of these magic numbers (though you can just set it on any specific view as well):

class MyBaseView(BaseModelView):
    ...
    named_filter_urls = True


class MyView(MyBaseView):
    ...
    column_filters = ['name', 'country']

This creates URLs like: http://.../admin/model/?flt_name_equals=foo&flt_country_contains=bar (*)

With this, your URLs can easily be contructed using the name of the attribute you want to filter on. As a bonus, you don't need to have a view instance available - important if you want to link to a view for a different model.

*(When selecting filters from UI, Flask-Admin will insert integers into the parameter keys. I'm not sure why it does that, but they don't appear necessary for simple filtering.)

like image 51
nfelger Avatar answered Oct 25 '22 09:10

nfelger


Flask-Admin defaults to the flt0_0=<value> syntax to be "robust across translations" if your app needs to support multiple languages. If you don't need to worry about translations, setting named_filter_urls=True is the way to go.

With named_filter_urls=True Flask-Admin generates filter query parameters like:

flt0_country_contains=<value>

The remaining integer after flt (0 in this case) is a sort key used to control the order of the filters as they appear in the UI when you have multiple filters defined. This number does not matter at all if you have a single filter.

For example, in my app I have named filters turned on. If I have multiple filters without the sort key the filters are displayed in the order they appear in the query string:

?flt_balance_smaller_than=100&flt_balance_greater_than=5

Yields: Default filter ordering

With a sort key added to the flt parameters, then I can force those filters to be displayed in a different order (flt1 will come before flt2):

?flt2_balance_smaller_than=100&flt1_balance_greater_than=5

Yields: Forced filter ordering

In practice it looks like this sort key can be any single character, e.g. this works too:

?fltB_balance_smaller_than=100&fltA_balance_greater_than=5

This behavior is ultimately defined in the Flask-Admin BaseModelView._get_list_filter_args() method here: https://github.com/flask-admin/flask-admin/blob/master/flask_admin/model/base.py#L1714-L1739

like image 7
Carlton Duffett Avatar answered Oct 25 '22 08:10

Carlton Duffett