简体   繁体   中英

How to move flask wtform from extending view to extended view and instantiate forms for all views?

To make my question clearer, here is a little application that takes a sentence input and outputs that sentence twice.

I have base.html :

<html>
  <head>
    <title> My site </title>
    <body>
    {% block content %}{% endblock %}
   </body>
</html>

and index.html :

{% extends "base.html" %}
{% block content %}
{{ s }}
<form action="" method="post" name="blah">
    {{ form.hidden_tag() }}
    {{ form.sentence(size=80) }}
    <input type="submit" value="Doubler"></p>
</form>
{% endblock %}

Here is part of views.py :

from forms import DoublerForm

@app.route('/index')
def index():
    form = DoublerForm()
    if form.validate_on_submit():
        s = form.sentence.data
        return render_template('index.html', form=form, s=str(s) + str(s))
    return render_template('index.html', form=form, s="")

And here is forms.py , without all the imports:

class DoublerForm(Form):
    sentence = StringField(u'Text')

This seems to work OK. But what I would like is to have my input form in the base.html template so that this shows up on all pages that extend it, not just the index page. How can I move the form to the base.html and instantiate the form for all views that extend base.html?

You can use the flask.g object and flask.before_request .

from flask import Flask, render_template, g
from flask_wtf import Form
from wtforms import StringField

@app.before_request
def get_default_context():
    """
    helper function that returns a default context used by render_template
    """
    g.doubler_form = DoublerForm()
    g.example_string = "example =D"

@app.route('/', methods=["GET", "POST"])
def index():
    form = g.get("doubler_form")
    if form.validate_on_submit():
        s = form.sentence.data
        return render_template('index.html', form=form, s=str(s) + str(s))
    return render_template('index.html', form=form, s="")

You can also explicitly define a context function

def get_default_context():
    """
    helper function that returns a default context used by render_template
    """
    context = {}
    context["doubler_form"] = form = DoublerForm()
    context["example_string"] = "example =D"
    return context

and is used like this

@app.route('/faq/', methods=['GET'])
def faq_page():
    """
    returns a static page that answers the most common questions found in limbo
    """
    context = controllers.get_default_context()
    return render_template('faq.html', **context)

Now, you'll have whatever objects you add to the context dictionary available in all templates that unpack the context dictionary.

index.html

{% extends "base.html" %}
{% block content %}
{{ s }}
{% endblock %}

base.html

<html>
  <head>
    <title> My site </title>
    <body>
    {% block content %}{% endblock %}
    <form action="" method="post" name="blah">
      {{ doubler_form.hidden_tag() }}
      {{ doubler_form.sentence(size=80) }}
      {{ example_string }}
      <input type="submit" value="Doubler"></p>
    </form>
   </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM