【问题标题】:How to "GET" request from JSON objects passed through HTML form如何从通过 HTML 表单传递的 JSON 对象“获取”请求
【发布时间】:2021-05-26 00:49:26
【问题描述】:

我想将我的输入字段提交给一个 json 对象并将其传递给 HTML 表格列表。我查看了类似的 StackOverflow 解决方案,但没有任何效果。 我可以将我的输入字段发送到 JSON 对象,但我不能“GET”请求它显示为 HTML 页面文本。

如何“获取”通过我的 HTML 表单传递的 json 对象?

This is what the solution should look like

This is what the page currently shows

main.py

from flask import Flask, render_template, redirect, url_for, request, session, flash, render_template_string, jsonify
import json

app = Flask(__name__)

headings = ["Name", "Channel", "Bots", "Status"]

@app.route("/")
def home():
    content = "data.js"
    return render_template("botList.html", headings=headings)


@app.route("/list", methods=["POST", "GET"])
def list():
    username = request.form["username"]
    channel = request.form["channel"]
    bots = request.form["bots"]
    status = request.form["status"]
    return render_template("botList.html", headings=headings,
                                            data=tableData,
                                            username=username,
                                            channel=channel,
                                            bots=bots,
                                            status=status)

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

您可以在 ma​​in.py 中看到我尝试传递表单输入,但是......没有运气。

botList.html

{% extends "base.html" %}

{% block content %}
<table id="table">
    <tr>
        {% for header in headings %}
        <th>{{ header }}</th>
        {% endfor %}
    </tr>
    <tr>
        {% for row in listData %}
        <tr>
            {% for cell in row %}
            <td>{{ cell }}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </tr>
</table>

<form method="POST" action="/list">
    <div>
        <label for="name">Username</label>
        <input type="text" name="username" id="username" placeholder="ex. janedoe"/>
    </div>
    <div>
        <label for="channel">Channel</label>
        <input type="text" name="channel" id="channel" placeholder="ex. TikTok US"/>
    </div>
    <div>
        <label for="bots">Bots</label>
        <input type="text" name="bots" id="bots" placeholder="ex. 1"/>
    </div>
    <div>
        <label for="Status">Status</label>
        <input type="text" name="status" id="status" placeholder="Offline" value="Offline"/>
    </div>
    <div>
        <button id="btn">Click to Add Bot</button>
    </div>
    <div id="msg">
        <pre></pre>
    </div>
</form>
<script>
    let listData = [];

    const addBot = (ev)=>{
        ev.preventDefault();  //to stop the form submitting
        let bot = {
            username: document.getElementById('username').value,
            channel: document.getElementById('channel').value,
            bots: document.getElementById('bots').value,
            status: document.getElementById('status').value
        }
        listData.push(bot);
        document.forms[0].reset(); // to clear the form for the next entries
        //document.querySelector('form').reset();

        //for display purposes only
        console.warn('added' , {listData} );
        let pre = document.querySelector('#msg pre');
        pre.textContent = '\n' + JSON.stringify(listData, '\t', 2);

        //saving to localStorage
        localStorage.setItem('listData', JSON.stringify(listData) );
    }
    document.addEventListener('DOMContentLoaded', ()=>{
        document.getElementById('btn').addEventListener('click', addBot);
        return listData
    });
</script>
{% endblock %}

base.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Program</title>
        <!-- INCLUDING JQUERY-->
        <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    </head>
    <body>
        <section>
            {% block content %}
            {% endblock %}
        </section>
    </body>
</html>

【问题讨论】:

  • 请说明您打算在客户端做什么以及您打算在服务器端做什么。目前,这些不能彼此分开。您将数据保存在客户端。由于使用的按钮类型,表单数据不应该被发送到服务器。但是,服务器上存在对表单数据的请求。 GET 和 POST 在服务器上没有区别。如果是这样,您希望如何将数据保存在服务器上?总而言之,您希望将哪种技术用于什么目的?
  • @Detlef 老实说,我不太确定。如何将数据发送到服务器?
  • 好的。我建议你对烧瓶做this tutorial。如果为按钮添加值为“submit”的属性“type”,数据将被发送到服务器。您的 javascript 代码将不再起作用。我是否正确假设您确实想将数据保存在服务器上?
  • @Detlef 是的,我想将数据保存在某个存储数据库中,以便以后及时访问。

标签: python json flask jinja2


【解决方案1】:

这是一个小例子,基本上是您尝试过的。不过,我建议您阅读this flask tutorial。有很多使用烧瓶框架进行开发的好例子。请四处看看。 我无法解释所有细节,这是错误的地方。

在下面的示例中,出于实用性的原因,我将使用一些通常不常见且应避免的做法。
请熟悉使用数据库或其他类型的存储来替换全局变量。

from dataclasses import dataclass
from flask import request 

# As an exception, since I cannot explain the use of a database to you in this 
# example, I use a global variable. You shouldn't actually do this, but it is 
# helpful in this case for the reason described above.
botlist = []

# For the same reason, I use a dataclass to map a model, which is later saved 
# within the defined list.
@dataclass
class Bot:
    username: str
    channel: str
    name: str
    status: str

@app.route('/bots', methods=['GET', 'POST'])
def bots():
    global botlist
    
    if request.method == 'POST':
        # If it is a POST request, create a bot object and append it to the list.
        bot = Bot(
            request.form['username'], 
            request.form['channel'], 
            request.form['name'], 
            request.form['status'], 
        )
        botlist.append(bot)

    # Re-render the page with the bots in the list.
    return render_template('bots.html', botlist=botlist)

基本上需要注意的是,一个jinja2模板是在服务端渲染然后发送给客户端的。但是,包含的 javascript 代码是在客户端上执行的。
为了简单起见,我在这个例子中没有使用 Javascript。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bots</title>
  </head>
  <body>
    <form method="post">
      <div>
        <label for="username">Username</label>
        <input type="text" name="username" id="username"/>
      </div>
      <div>
        <label for="channel">Channel</label>
        <input type="text" name="channel" id="channel"/>
      </div>
      <div>
        <label for="Name">Name</label>
        <input type="text" name="name" id="name"/>
      </div>
      <div>
        <label for="status">Status</label>
        <input type="text" name="status" id="status"/>
      </div>
      <button type="submit">Add Bot</button>
    </form>
    <hr />
    <table>
      <thead>
        <tr>
          <th>Username</th>
          <th>Channel</th>
          <th>Name</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        {% for bot in botlist -%}
        <tr>
          <td>{{ bot.username }}</td>
          <td>{{ bot.channel }}</td>
          <td>{{ bot.name }}</td>
          <td>{{ bot.status }}</td>
        </tr>
        {% endfor -%}
      </tbody>
    </table>
  </body>
</html>

【讨论】:

  • 谢谢你的工作!我想刷新页面仍然有数据,如何将数据保存在本地存储/数据库而不是全局变量中?
  • @mattwelter 使用flask_sqlalchemy 并创建模型然后创建表,然后您可以保存和查询数据库中的条目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 2019-11-23
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-01
相关资源
最近更新 更多