Skip to content

Commit

Permalink
Use variable name as default attribute.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcarp committed Oct 22, 2015
1 parent 2222480 commit ccd1966
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Quickstart
@app.route('/albums')
def get_albums():
query = AlbumFilterSet.filter()
query = AlbumFilterSet().filter()
return flask.jsonify(query.all())
.. _marshmallow-sqlalchemy: https://marshmallow-sqlalchemy.readthedocs.org/
Expand Down
4 changes: 2 additions & 2 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Individual filters can also be declared manually as class variables:
model = Album
query = session.query(Album)
parser = parser
name__like = Filter('name', fields.Str(), operator=ILike)
genre__in = Filter('genre', fields.List(fields.Str), operator=In)
name = Filter(fields.Str(), operator=ILike)
genre = Filter(fields.List(fields.Str), operator=In)
Customizing query format
------------------------
Expand Down
10 changes: 5 additions & 5 deletions filteralchemy/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
class Filter(object):
"""Base filter.
:param str attr: Model attribute name
:param Field field: Field to deserialize filter parameter
:param str attr: Model attribute name
:param str label: Lookup key on input dictionary
:param operator: Operator or filter callable
"""
def __init__(self, attr=None, field=None, label=None, operator=operators.Equal):
self.attr = attr
def __init__(self, field=None, attr=None, label=None, operator=operators.Equal):
self.field = field
self.attr = attr
self.label = label
self.operator = operator

def filter(self, query, model, value):
def filter(self, query, model, attr, value):
operator = self.operator() if isinstance(self.operator, type) else self.operator
return operator(query, model, self.attr, value)
return operator(query, model, self.attr or attr, value)
11 changes: 5 additions & 6 deletions filteralchemy/filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ def __new__(mcs, name, bases, attrs):
klass = super(FilterSetMeta, mcs).__new__(mcs, name, bases, attrs)
klass.opts = FilterSetOptions(getattr(klass, 'Meta'))
klass.filters = dict(
declared_fields +
mcs.get_model_filters(klass) +
mcs.get_inherited_filters(klass) +
mcs.get_model_filters(klass)
declared_fields
)
return klass

Expand Down Expand Up @@ -73,12 +73,12 @@ def get_model_filters(mcs, klass):
)
operators = overrides.get('operators') or opts.operators
for operator in operators:
name = underscore_formatter(prop.key, operator.label)
operator_name = (
operator.label
if operator != opts.default_operator
else None
)
name = underscore_formatter(prop.key, operator_name)
label = opts.formatter(prop.key, operator_name)
filter_ = mcs.make_filter(prop, field, label, operator, klass)
filters.append((name, filter_))
Expand All @@ -89,8 +89,7 @@ def make_filter(mcs, prop, field, label, operator, klass):
opts = klass.opts
if operator.multiple:
field = opts.list_class(field)
filter_ = Filter(prop.key, field, label=label, operator=operator)
return filter_
return Filter(field, prop.key, label=label, operator=operator)

class FilterSet(six.with_metaclass(FilterSetMeta, object)):
"""
Expand Down Expand Up @@ -152,5 +151,5 @@ def filter(self):
for label, filter in self.filters.items():
value = args.get(filter.label or label)
if value is not None:
query = filter.filter(query, self.opts.model, value)
query = filter.filter(query, self.opts.model, label, value)
return query
2 changes: 1 addition & 1 deletion tests/test_filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ class Meta:
column_overrides = {
'sales': {'field': fields.Float()},
}
assert isinstance(ModelFilterSet.filters['sales__eq'].field, fields.Float)
assert isinstance(ModelFilterSet.filters['sales'].field, fields.Float)
10 changes: 6 additions & 4 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class Meta:
query = session.query(models.Album)
operators = (operators.Equal, operators.In)
parser = parser
name__like = Filter('name', fields.Str(), operator=operators.Like)
sales__modulo = Filter(field=fields.Str(), operator=modulo)
genre = Filter(fields.Str(), operator=operators.Like)
sales__modulo = Filter(fields.Str(), operator=modulo)
return ModelFilterSet

@pytest.fixture
Expand All @@ -38,11 +38,13 @@ def albums(self, models, session):
name='A Night at the Opera',
date=datetime.date(1975, 11, 21),
sales=12000000,
genre='rock',
),
models.Album(
name='The Works',
date=datetime.date(1984, 2, 27),
sales=5000000,
genre='synth',
),
]
for album in albums:
Expand Down Expand Up @@ -73,10 +75,10 @@ def test_filter_in(self, app, albums, session, ModelFilterSet):
assert set(query.all()) == set(albums)

def test_declared_filter(self, app, albums, session, ModelFilterSet):
with app.test_request_context('/?name__like=%Night%'):
with app.test_request_context('/?genre=syn%'):
query = ModelFilterSet().filter()
assert query.count() == 1
assert query.first() == albums[0]
assert query.first() == albums[1]

def test_custom_filter(self, app, albums, session, ModelFilterSet):
with app.test_request_context('/?sales__modulo=3000000'):
Expand Down

0 comments on commit ccd1966

Please sign in to comment.