Flask-AppBuilder icon indicating copy to clipboard operation
Flask-AppBuilder copied to clipboard

Enable multiple columns ordering for sqla

Open gbrault opened this issue 3 years ago • 2 comments

https://github.com/dpgaspar/Flask-AppBuilder/blob/a996b9b7aeed6b93b62a2c4a75db8375dd34268f/flask_appbuilder/models/sqla/interface.py#L179

I propose to change the code as follow (adding very few lines to original code) Could you review and tell me doing a Pull Request please?

Ordering with multiple columns would then be declared as base_order = (('owner','categorie','propriete'), 'asc') in a view

    def apply_order_by(
        self,
        query: Query,
        order_column: Any,
        order_direction: str,
        aliases_mapping: Dict[str, AliasedClass] = None,
    ) -> Query:
        if isinstance(order_column, str):
            if order_column != "":
                # if Model has custom decorator **renders('<COL_NAME>')**
                # this decorator will add a property to the method named *_col_name*
                if hasattr(self.obj, order_column):
                    if hasattr(getattr(self.obj, order_column), "_col_name"):
                        order_column = getattr(self._get_attr(order_column), "_col_name")
                _order_column = self._get_attr(order_column) or order_column

                if is_column_dotted(order_column):
                    root_relation = get_column_root_relation(order_column)
                    # On MVC we still allow for joins to happen here
                    if not self.is_model_already_joined(
                        query, self.get_related_model(root_relation)
                    ):
                        query = self._query_join_relation(
                            query, root_relation, aliases_mapping=aliases_mapping
                        )
                    column_leaf = get_column_leaf(order_column)
                    _alias = self.get_alias_mapping(root_relation, aliases_mapping)
                    _order_column = getattr(_alias, column_leaf)
                if order_direction == "asc":
                    query = query.order_by(asc(_order_column))
                else:
                    query = query.order_by(desc(_order_column))
            return query
        elif isinstance(order_column, tuple):
            for col in order_column:
                query = self.apply_order_by(query, col, order_direction)
            return query
        else:
            return query

gbrault avatar Oct 19 '22 09:10 gbrault

Thank you, I've just tested here and it works great. I'm not in a position to review or critique, but I do wonder if there would be applications for different sorting by different columns, e.g:

(('owner', 'asc'),('categorie', 'asc'),('propriete','desc'))

To make this more flexible?

steve-embling avatar Dec 05 '22 12:12 steve-embling

Of course, this is a good idea!

gbrault avatar Dec 05 '22 14:12 gbrault