I want to have a search form to query the database and display the results from the search below it. I don't want any confirmation warning to appear when refreshing the page. Also I want to know if this can be done with a single view function as all the tutorials I've seen use more than one. Like this one and this one.
This is working but it shows a warning that asks for confirmation when clicking the refresh button on the browser:
main.py
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
form = SearchForm()
query = form.data['search']
if query != '':
results = Foo.query.filter(Foo.name.like('%'+query+'%')).all()
return render_template('index.html', form=form, query=query, results=results)
return render_template('index.html', form=form)
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
class SearchForm(FlaskForm):
search = StringField('search', validators=[DataRequired()])
templates/index.html
{% block page_content %}
<div class="page-header">
<form style="display: inline;" action="{{ url_for('index') }}" method="post" name="search">
{{ form.search(size=20) }}
<input type="submit" value="Search">
</form>
{% if results %}
<h1>Search results for "{{ query }}":</h1>
{{ results }}
{% endif %}
</div>
{% endblock page_content %}
This is what I would like but it gives a page not redirecting properly error
:
@app.route('/', methods=['GET', 'POST'])
def index():
form = SearchForm(request.form)
if form.validate:
session['query'] = form.data['search']
return redirect(url_for('index'))
if 'query' in session:
results = Foo.query.filter(Foo.name.like('%'+session.get('query')+'%')).all()
return render_template('index.html', form=form, query=session.get('query'), results=results)
else:
return render_template('index.html', form=form)
You can have a single function to render the search page and then after form.validate_on_submit()
query the database and return the results. For the search results add an if statetment to display them on the same template as the search form.
@app.route('/search', methods=['GET', 'POST'])
def search():
form = SearchForm()
if form.validate_on_submit():
search_term = form.query.data
results = Foo.query.all()
return render_template('search.html', form=form, results=results)
return render_template('search.html', form=form)
search.html
{% block content%}
<form method="post">
{{ form.csrf_token }}
{{ form.query }}
{{ form.submit }}
{% if results %}
{{ results }}
{% endif %}
</form>
{% endblock %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With