sravan_kumar
sravan_kumar

Reputation: 1129

Flask: How do I place Forms in Base jinja2 Template?

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.

  1. How do I pass the form object of base template while calling the derived template?
  2. Is my approach right to what I want to achieve? If there are any other, please suggest.

Thanking you in advance

Upvotes: 2

Views: 6918

Answers (1)

Sean Vieira
Sean Vieira

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

Related Questions