Reputation: 1129
I am new to Flask and am writing a simple Flask application with search facility. Similar to google search, I want to retain the search input box in the search result page while showing the results.So, I placed search form in the base template and a derived search result template from the base template to show both search form and search results.
For this, I did the following:-
A Base Template(base.html) with Page metadata and Form(which should basically be present even in the result page).
<html>
<head>
{% if title %}
<title>{{title}}</title>
{% else %}
<title>Search</title>
{% endif %}
</head>
<body>
<h1>Search </h1>
<form action="/series_search" method="post" name="search">
{{form.hidden_tag()}}
<p>
Please enter query: <br>
{{form.search(size=10)}}
</p>
<p><input type="submit" value="Search"></p>
</form>
<br>
{% block content %}{% endblock %}
</body>
</html>
The derived template(derived.html) has the following code, which is inhering the base template(which has the search template):
{% extends "base.html" %}
{% block content %}
<h1>Search Result</h1>
{% if result %}
<p> Title: {{result.title}}</p>
{% else %}
<p> search not found!!</p>
{% endif %}
{% endblock %}
And, In the view, the following
@app.route('/search', methods = ['POST', 'GET'])
def search():
form = SearchForm()
if form.validate_on_submit():
print "form validated"
query = form.search.data
result = Lib.get_result(query)
return render_template('derived.html', result = result)
return render_template('search.html',
title = 'Search',
form = form)
If I enter the query and submit the search form, I get the following error,
....
....
File "/Users/webapp/app/templates/derived.html", line 1, in top-level template code
{% extends "search.html" %}
File "/Users/webapp/app/templates/search.html", line 12, in top-level template code
{{form.hidden_tag()}}
File "/Users/webapp/flask/lib/python2.7/site-packages/jinja2/environment.py", line 397, in getattr
return getattr(obj, attribute)
So, Basically after the submit button is pressed, the view renders the derived.html which is derived from base.html. The base.html has a form which should be set.
Thanking you in advance
Upvotes: 2
Views: 6918
Reputation: 159955
You just need to pass the form keyword argument to your other render_template
call.
return render_template('derived.html', result=result)
should instead be:
return render_template('derived.html', result=result, form=form)
The reason this is needed is because the web is stateless - the rendered template is not preserved on Flask's side. The HTML is sent to the client and then everything is done, as far as Flask is concerned. The POST request is a separate request from the server's perspective and the only thing that is called is the render_template('derived')
call. There is no "memory" of having created a form and sent it to search.html
.
Upvotes: 6