Reputation: 486
I am having trouble putting all these pieces together. I am getting values from a form POST the name/id in the form are the actual column names in my database table.
The idea here is to filter cascading select2 inputs to create a dynamic filter. For example my current 3 select names are field, name. If I select I field I only want to provide only the names in that field. If no field is selected I provide all the names (and so on). Obviously the production model would have more than 2.
I am trying to iterate the request.args in order to get the name and the value, then add to the filter. below is my code.
@bp.route('/wells/name')
def wells_name():
if request.args:
qry = Wells.query
for var in request.args:
qry = qry.filter(getattr(Wells, var) == request.args['{}'.format(var)])
query = qry.with_entities(Wells.name).group_by(Wells.name).order_by(Wells.name)
else:
query = Wells.query.with_entities(Wells.name).group_by(Wells.name) \
.order_by(Wells.name)
I am using the following code to get the value of the variable;
request.args['{}'.format(var)]
The following code to represent Wells.variablename (Wells.field or Wells.name in this scenario)
getattr(Wells, var)
and the following example to try and 'put it all together' https://stackoverflow.com/questions/39137911/build-dynamic-filters-in-sqlalchemy-python.
Upvotes: 0
Views: 353
Reputation: 486
OK, this problem was definitely not what I had anticipated. I move the with_entities before the iteration of filtering and it solved the problem. I'm sure there is still room for improvement but it is vastly improved over what I had. Here is the new code.
@bp.route('/wells/name')
def wells_name():
if request.args:
query = Wells.query.with_entities(Wells.field, Wells.name) \
.group_by(Wells.field, Wells.name).order_by(Wells.name)
for var in request.args:
query = query.filter(getattr(Wells, var) \
.ilike('%{}%'.format(request.args['{}'.format(var)])))
else:
query = Wells.query.with_entities(Wells.name).group_by(Wells.name) \
.order_by(Wells.name)
And the old code
@bp.route('/wells/name')
def wells_name():
if 'field' in request.args and 'name' not in request.args:
field = request.args['field']
query = Wells.query.filter(Wells.field.ilike('%{}%'.format(field))) \
.with_entities(Wells.name).group_by(Wells.name).order_by(Wells.name)
elif 'field' not in request.args and 'name' in request.args:
name = request.args['name']
query = Wells.query.filter(Wells.name.ilike('%{}%'.format(name))) \
.with_entities(Wells.name).group_by(Wells.name).order_by(Wells.name)
elif 'field' in request.args and 'name' in request.args:
field = request.args['field']
name = request.args['name']
query = Wells.query.filter(Wells.field.ilike('%{}%'.format(field)), \
Wells.name.ilike('%{}%'.format(name))) \
.with_entities(Wells.name).group_by(Wells.name).order_by(Wells.name)
else:
query = Wells.query.with_entities(Wells.name).group_by(Wells.name) \
.order_by(Wells.name)
With more variables obviously the 'old code' would have grown significantly, with even just a 3rd added.
Upvotes: 1