Commit f214557f authored by Bastien Sevajol's avatar Bastien Sevajol Committed by Bastien Sevajol (algoo.fr)

Fix filter by columns with same model overriding

parent 4ff21f12
...@@ -615,16 +615,29 @@ class ModelView(BaseModelView): ...@@ -615,16 +615,29 @@ class ModelView(BaseModelView):
else: else:
columns = self._get_columns_for_field(attr) columns = self._get_columns_for_field(attr)
# If filter related to relation column (represented by
# relation_name.target_column) we collect here relation name
joined_column_name = None
if '.' in name:
joined_column_name = name.split('.')[0]
if len(columns) > 1: if len(columns) > 1:
raise Exception('Can not filter more than on one column for %s' % name) raise Exception('Can not filter more than on one column for %s' % name)
column = columns[0] column = columns[0]
if self._need_join(column.table) and name not in self.column_labels: if self._need_join(column.table) and name not in self.column_labels:
visible_name = '%s / %s' % ( if joined_column_name:
self.get_column_name(column.table.name), visible_name = '%s / %s / %s' % (
self.get_column_name(column.name) joined_column_name,
) self.get_column_name(column.table.name),
self.get_column_name(column.name)
)
else:
visible_name = '%s / %s' % (
self.get_column_name(column.table.name),
self.get_column_name(column.name)
)
else: else:
if not isinstance(name, string_types): if not isinstance(name, string_types):
visible_name = self.get_column_name(name.property.key) visible_name = self.get_column_name(name.property.key)
...@@ -640,10 +653,19 @@ class ModelView(BaseModelView): ...@@ -640,10 +653,19 @@ class ModelView(BaseModelView):
options=self.column_choices.get(name), options=self.column_choices.get(name),
) )
key_name = column
# In case of filter related to relation column filter key
# must be named with relation name (to prevent following same
# target column to replace previous)
if joined_column_name:
key_name = "{}.{}".format(joined_column_name, column)
for f in flt:
f.key_name = key_name
if joins: if joins:
self._filter_joins[column] = joins self._filter_joins[key_name] = joins
elif self._need_join(column.table): elif self._need_join(column.table):
self._filter_joins[column] = [column.table] self._filter_joins[key_name] = [column.table]
return flt return flt
...@@ -878,7 +900,9 @@ class ModelView(BaseModelView): ...@@ -878,7 +900,9 @@ class ModelView(BaseModelView):
# Figure out joins # Figure out joins
if isinstance(flt, sqla_filters.BaseSQLAFilter): if isinstance(flt, sqla_filters.BaseSQLAFilter):
path = self._filter_joins.get(flt.column, []) # If no key_name is specified, use filter column as filter key
filter_key = flt.key_name or flt.column
path = self._filter_joins.get(filter_key, [])
query, joins, alias = self._apply_path_joins(query, joins, path, inner_join=False) query, joins, alias = self._apply_path_joins(query, joins, path, inner_join=False)
......
...@@ -8,7 +8,7 @@ class BaseFilter(object): ...@@ -8,7 +8,7 @@ class BaseFilter(object):
""" """
Base filter class. Base filter class.
""" """
def __init__(self, name, options=None, data_type=None): def __init__(self, name, options=None, data_type=None, key_name=None):
""" """
Constructor. Constructor.
...@@ -18,10 +18,13 @@ class BaseFilter(object): ...@@ -18,10 +18,13 @@ class BaseFilter(object):
List of fixed options. If provided, will use drop down instead of textbox. List of fixed options. If provided, will use drop down instead of textbox.
:param data_type: :param data_type:
Client-side widget type to use. Client-side widget type to use.
:param key_name:
Optional name who represent this filter.
""" """
self.name = name self.name = name
self.options = options self.options = options
self.data_type = data_type self.data_type = data_type
self.key_name = key_name
def get_options(self, view): def get_options(self, view):
""" """
......
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