0

I'm making a Flask app for an online dictionary, but the FlaskForm I've made doesn't return anything when submitted. Here's my app.py:

from flask import Flask, render_template, url_for, redirect, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired

app = Flask(__name__)
app.config['SECRET_KEY'] = "bbe039da711aa33120ffe25823ae104d1daa0d8efc3e8b3ceb37a4819bf3f695"


class SearchForm(FlaskForm):
    term = StringField(label=('Search for:'), validators=[DataRequired()])
    submit = SubmitField(label=('Search'))


d = {
    "我": {
        "eng": "I, me",
        "pin": "ng4"
    },
    "你": {
        "eng": "you",
        "pin": "nyi4"
    }
}


@app.route("/", methods=['GET', 'POST'])
def search():
    form = SearchForm()
    if request.method == "POST":
        hanterm = form.term.data
        postdata = d[hanterm]
        return render_template("results.html", title=hanterm, postdata=postdata)
    return render_template("index.html", title="Search", form=form)


if __name__ == '__main__':
    app.run(debug=True)

My index.html (which contains the template that results.html extends from):

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">

    {% if title %}
        <title>Flask Blog - {{ title }}</title>
    {% else %}
        <title>Flask Blog</title>
    {% endif %}
</head>
<body>
    <div class="content-section mt-2 ml-2">
        <form method="GET" autocomplete="off" action="{{ url_for('search') }}" enctype="multipart/form-data">
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Search term:</legend>
                <div class="form-group">
                    {{ form.csrf_token() }}
                    {{ form.term.label(class="form-control-label") }}
                    {{ form.term(class="form-control form-control-lg") }}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>


    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

And my results.html:

{% extends "index.html" %}
{% block content %}
    <p>Reading: {{ postdata["pin"] }}</p>
    <p>English: {{ postdata["eng"] }}</p>
{% endblock %}

The user enters a Han character into the input field and submits, and the character should then be asssigned to hanterm and its dictionary assigned to postdata, and then postdata is sent to results.html so that its values can be printed.

E.g. if I typed 我, hanterm='我' and

postdata = {
        "eng": "I, me",
        "pin": "ng4"
    }

whose values are then printed in results.html.

However, when I submit, nothing happens. When I tried to print form.term.data, I got nothing. I previously had two routes - one for the home page and the other for the page of results, but I kept on getting Keyerrors and thought that was cause of the hanterm variable not going to the results function (which contained these bits:

        hanterm = form.term.data
        postdata = d[hanterm]
        return render_template("results.html", title=hanterm, postdata=postdata)

and the render_template for results.html), so I tried using global variables, session variables etc. What should I do to fix this?

1 Answers1

1

The problem is that your HTML form specifies method="GET" while your Python is checking for if request.method == "POST":

If you are using GET, the form data is contained in the request URL, so you should be accessing it in Flask with something like request.args.get("term").

I would recommend not using a flask form for a search function but instead using a simple HTML GET form and checking for request arguments on every request to the page, something like this:

@app.route("/", methods=["GET"])
def search():
    hanterm = request.args.get("term")
    if hanterm:
        return render_template(
            "results.html",
            title=hanterm,
            postdata=d[hanterm],
        )
    return render_template("index.html", title="Search")