Commit 7bd79342 authored by Tong Bu's avatar Tong Bu

support multi column sort with column_default_sort

parent f5628d79
...@@ -482,13 +482,21 @@ class ModelView(BaseModelView): ...@@ -482,13 +482,21 @@ class ModelView(BaseModelView):
for c in self.column_sortable_list: for c in self.column_sortable_list:
if isinstance(c, tuple): if isinstance(c, tuple):
column, path = tools.get_field_with_path(self.model, c[1]) if isinstance(c[1], tuple):
column_name = c[0] column, path = [], []
for item in c[1]:
column_item, path_item = tools.get_field_with_path(self.model, item)
column.append(column_item)
path.append(path_item)
column_name = c[0]
else:
column, path = tools.get_field_with_path(self.model, c[1])
column_name = c[0]
else: else:
column, path = tools.get_field_with_path(self.model, c) column, path = tools.get_field_with_path(self.model, c)
column_name = text_type(c) column_name = text_type(c)
if path and hasattr(path[0], 'property'): if path and (hasattr(path[0], 'property') or isinstance(path[0], list)):
self._sortable_joins[column_name] = path self._sortable_joins[column_name] = path
elif path: elif path:
raise Exception("For sorting columns in a related table, " raise Exception("For sorting columns in a related table, "
...@@ -828,15 +836,9 @@ class ModelView(BaseModelView): ...@@ -828,15 +836,9 @@ class ModelView(BaseModelView):
column = sort_field if alias is None else getattr(alias, sort_field.key) column = sort_field if alias is None else getattr(alias, sort_field.key)
if sort_desc: if sort_desc:
if isinstance(column, tuple): query = query.order_by(desc(column))
query = query.order_by(*map(desc, column))
else:
query = query.order_by(desc(column))
else: else:
if isinstance(column, tuple): query = query.order_by(column)
query = query.order_by(*column)
else:
query = query.order_by(column)
return query, joins return query, joins
...@@ -844,11 +846,26 @@ class ModelView(BaseModelView): ...@@ -844,11 +846,26 @@ class ModelView(BaseModelView):
order = super(ModelView, self)._get_default_order() order = super(ModelView, self)._get_default_order()
if order is not None: if order is not None:
field, direction = order if isinstance(order[1], bool):
field, direction = order
attr, joins = tools.get_field_with_path(self.model, field)
attr, joins = tools.get_field_with_path(self.model, field) return attr, joins, direction
else:
attrs, joins, directions = [], [], []
for order_item in order:
if isinstance(order_item, tuple):
field, direction = order_item
elif isinstance(order_item, string_types):
field, direction = order_item, False
attr, path = tools.get_field_with_path(self.model, field)
attrs.append(attr)
joins.append(path)
directions.append(direction)
return attr, joins, direction return attrs, joins, directions
return None return None
...@@ -858,14 +875,22 @@ class ModelView(BaseModelView): ...@@ -858,14 +875,22 @@ class ModelView(BaseModelView):
sort_field = self._sortable_columns[sort_column] sort_field = self._sortable_columns[sort_column]
sort_joins = self._sortable_joins.get(sort_column) sort_joins = self._sortable_joins.get(sort_column)
query, joins = self._order_by(query, joins, sort_joins, sort_field, sort_desc) if isinstance(sort_field, list):
for field_item, join_item in zip(sort_field, sort_joins):
query, joins = self._order_by(query, joins, join_item, field_item, sort_desc)
else:
query, joins = self._order_by(query, joins, sort_joins, sort_field, sort_desc)
else: else:
order = self._get_default_order() order = self._get_default_order()
if order: if order:
sort_field, sort_joins, sort_desc = order sort_field, sort_joins, sort_desc = order
query, joins = self._order_by(query, joins, sort_joins, sort_field, sort_desc) if isinstance(sort_field, list):
for sort_field_item, sort_joins_item, sort_desc_item in zip(sort_field, sort_joins, sort_desc):
query, joins = self._order_by(query, joins, sort_joins_item, sort_field_item, sort_desc_item)
else:
query, joins = self._order_by(query, joins, sort_joins, sort_field, sort_desc)
return query, joins return query, joins
......
...@@ -360,6 +360,12 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -360,6 +360,12 @@ class BaseModelView(BaseView, ActionsMixin):
class MyModelView(BaseModelView): class MyModelView(BaseModelView):
column_sortable_list = ('name', ('user', 'user.username')) column_sortable_list = ('name', ('user', 'user.username'))
You can also specify multiple fields to be used while sorting::
class MyModelView(BaseModelView):
column_sortable_list = (
'name', ('user', ('user.first_name', 'user.last_name')))
When using SQLAlchemy models, model attributes can be used instead When using SQLAlchemy models, model attributes can be used instead
of strings:: of strings::
...@@ -381,6 +387,13 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -381,6 +387,13 @@ class BaseModelView(BaseView, ActionsMixin):
class MyModelView(BaseModelView): class MyModelView(BaseModelView):
column_default_sort = ('user', True) column_default_sort = ('user', True)
You can also sort by multiple columns. In following example,
items will be sorted by email ascending first, and then sorted by user
descending::
class MyModelView(BaseModelView):
column_default_sort = ('email', ('user', True))
""" """
column_searchable_list = ObsoleteAttr('column_searchable_list', column_searchable_list = ObsoleteAttr('column_searchable_list',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment