[selectors, facet] make is_instance and other EClassSelector subclass gather entity classes from 'select' and 'filtered_variable' context information. Closes #1796732
This allow for instance to use the filter form on rqlst where the filtered variable is not selected
--- a/selectors.py Fri Jul 01 16:20:57 2011 +0200
+++ b/selectors.py Fri Jul 01 18:42:36 2011 +0200
@@ -255,12 +255,19 @@
* if `entity` is specified, return score for this entity's class
- * elif `row` is specified, return score for the class of the entity
- found in the specified cell, using column specified by `col` or 0
+ * elif `rset`, `select` and `filtered_variable` are specified, return score
+ for the possible classes for variable in the given rql :class:`Select`
+ node
+
+ * elif `rset` and `row` are specified, return score for the class of the
+ entity found in the specified cell, using column specified by `col` or 0
- * else return the sum of scores for each entity class found in the column
- specified specified by the `col` argument or in column 0 if not specified,
- unless:
+ * elif `rset` is specified return score for each entity class found in the
+ column specified specified by the `col` argument or in column 0 if not
+ specified
+
+ When there are several classes to be evaluated, return the sum of scores for
+ each entity class unless:
- `once_is_enough` is False (the default) and some entity class is scored
to 0, in which case 0 is returned
@@ -276,32 +283,37 @@
self.accept_none = accept_none
@lltrace
- def __call__(self, cls, req, rset=None, row=None, col=0, accept_none=None,
+ def __call__(self, cls, req, rset=None, row=None, col=0, entity=None,
+ select=None, filtered_variable=None,
+ accept_none=None,
**kwargs):
- if kwargs.get('entity'):
- return self.score_class(kwargs['entity'].__class__, req)
+ if entity is not None:
+ return self.score_class(entity.__class__, req)
if not rset:
return 0
- score = 0
- if row is None:
+ if select is not None and filtered_variable is not None:
+ etypes = set(sol[filtered_variable.name] for sol in select.solutions)
+ elif row is None:
if accept_none is None:
accept_none = self.accept_none
- if not accept_none:
- if any(rset[i][col] is None for i in xrange(len(rset))):
- return 0
- for etype in rset.column_types(col):
- if etype is None: # outer join
- return 0
- escore = self.score(cls, req, etype)
- if not escore and not self.once_is_enough:
- return 0
- elif self.once_is_enough:
- return escore
- score += escore
+ if not accept_none and \
+ any(rset[i][col] is None for i in xrange(len(rset))):
+ return 0
+ etypes = rset.column_types(col)
else:
etype = rset.description[row][col]
- if etype is not None:
- score = self.score(cls, req, etype)
+ # may have None in rset.description on outer join
+ if etype is None:
+ return 0
+ etypes = (etype,)
+ score = 0
+ for etype in etypes:
+ escore = self.score(cls, req, etype)
+ if not escore and not self.once_is_enough:
+ return 0
+ elif self.once_is_enough:
+ return escore
+ score += escore
return score
def score(self, cls, req, etype):
--- a/web/views/facets.py Fri Jul 01 16:20:57 2011 +0200
+++ b/web/views/facets.py Fri Jul 01 18:42:36 2011 +0200
@@ -198,7 +198,7 @@
class FilterTable(FacetFilterMixIn, AnyRsetView):
__regid__ = 'facet.filtertable'
- __select__ = non_final_entity() & has_facets()
+ __select__ = has_facets()
wdg_stack_size = 8
def call(self, vid, divid, vidargs, cssclass=''):