首页 > 解决方案 > Form.term.data 不返回任何内容

问题描述

我正在为在线词典制作 Flask 应用程序,但我制作的 FlaskForm 在提交时没有返回任何内容。这是我的 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)

我的 index.html(其中包含 results.html 扩展的模板):

<!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>

还有我的 results.html:

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

用户在输入字段中输入一个汉字并提交,然后该字符应被分配给hanterm并将其字典分配给postdata,然后postdata发送到 results.html 以便可以打印其值。

例如,如果我输入了我,hanterm='我'并且

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

然后将其值打印在 results.html 中。

但是,当我提交时,什么也没有发生。当我尝试打印 form.term.data 时,我一无所获。我以前有两条路线 - 一条用于主页,另一条用于结果页面,但我不断收到 Keyerrors 并认为这是导致 hanterm 变量没有进入结果函数的原因(其中包含这些位:

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

和results.html的render_template),所以我尝试使用全局变量、会话变量等。我应该怎么做才能解决这个问题?

标签: pythonhtmlflaskjinja2cjk

解决方案


问题是您的 HTML 表单method="GET"在您的 Python 检查时指定if request.method == "POST":

如果您使用的是GET,则表单数据包含在请求 URL 中,因此您应该在 Flask 中使用类似request.args.get("term").

我建议不要将烧瓶表单用于搜索功能,而是使用简单的 HTMLGET表单并检查对页面的每个请求的请求参数,如下所示:

@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")

推荐阅读