表单提交后自动查询Flask接口

问题描述 投票:0回答:1

我正在创建一个基本的 Flask 应用程序来展示我在 python 中为了好玩而完成的愚蠢的迷你项目(最初是为 CLI 创建的)。其中之一是可视化约翰·康威的生命游戏 (GOL) 的程序。如果你不知道那是什么,你不需要知道,只需知道它是一个不断变化的二进制矩阵即可。

用户提交一个表单,指定网格大小的整数和 0 到 1 之间的浮点数以自动生成初始状态下活细胞的密度,我希望网格显示在表单下方并切换到每 0.1 秒进入下一个状态(不刷新页面)。

我对 Vanilla Python 和 HTML 有相当多的了解,但我是 Flask 新手,对 JavaScript 一无所知。我 ChatGPTed 了一些我认为可以工作的 JS,但是提交后表单下方没有任何显示。附带说明一下,如果可能的话,我希望在提交表单之前不要开始查询 Flask,而 ChatGPT 的 JS 不会这样做。以下是与应用程序的 GOL 部分相关的代码:

在app.py中:

import game_of_life
from markupsafe import Markup

game = None
@app.route("/create_GOL", methods=['post'])
def create_game():
    density, size = request.form['density'], request.form['size']
    global game
    # initializes game in GameOfLife class
    game = game_of_life.GameOfLife(int(size), float(density))
    return render_template("index.html")

@app.route("/next_state", methods=['get'])
def next_state():
    # runs method to update "game" to the next state in-place
    game.find_next_state()
    # returns the HTML-friendly version of the matrix
    return Markup('<br>'.join(''.join(('  ', '██')[j] for j in i) for i in game.m))

在index.html中:

<form action="create_GOL", method="post">
    <label for="density">Density (0-1): </label>
    <input type="number" name="density", step="any", min=0, max=1>
    <label for="size">Size: </label>
    <input type="number" name="size", min=1, max=100>
    <input type="submit" value="Submit">
</form><br>
<div id="game-state"></div>
<script>
    function updateGameState() {
        fetch('/next_state')
            .then(response => response.json())
            .then(data => document.getElementById('game-state').innerText = data.state)
    }
    setInterval(updateGameState, 100);
</script>

我应该如何修改我的代码: 1.实际展示一些东西 2. 在表单实际提交之前不要浪费查询

或者,我应该使用不同的方法吗?

javascript html python-3.x flask interface
1个回答
0
投票

好的,所以您的代码中几乎没有问题。

您还没有发布带有路由“/”的Python代码,我假设它返回index.html。

当您提交表单并点击“create_GOL”路线时,您再次发送相同的 index.html 文件,该文件会重置更新循环,因此您看不到任何内容。提交事件后,您立即开始下一个循环,而无需初始化游戏。

我已经修改了 python 和 javascript 代码,这应该可以工作(我在随机二维数组上测试了它)

from flask import Flask,render_template,request, jsonify
import numpy as np

app = Flask(__name__)
game = None

@app.route('/')
def index():
    return render_template('index.html')

@app.route("/create_GOL", methods=['post'])
def create_game():
    global game
    jsonData = request.get_json()
    density, size = float(jsonData['density']), int(jsonData['size'])
    game = game_of_life.GameOfLife(size,density)
    return {
            'response' : 'Created'
        }

@app.route("/next_state", methods=['get'])
def next_state():
    global game
    game.find_next_state()
    ret = '<br>'.join(''.join(('  ', '██')[j] for j in i) for i in game.m)
    return jsonify(ret)

<body>
    <form action="create_GOL" , method="post" onsubmit="doSubmit();return false">
        <label for="density">Density (0-1): </label>
        <input id='density' type="number" name="density" , step="any" , min=0, max=1>
        <label for="size">Size: </label>
        <input id='size' type="number" name="size" , min=1, max=100>
        <input type="submit" value="Submit">
    </form><br>
    <div id="game-state"></div>
    <script>

        function updateGameState() {
            fetch('/next_state')
                .then(response => response.json())
                .then(data => { document.getElementById('game-state').innerHTML = data })
        }

        function doSubmit() {
            const jsonData = { density: document.getElementById('density').value, size: document.getElementById('size').value };

            // Set up options for the fetch request
            const options = {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json' // Set content type to JSON
                },
                body: JSON.stringify(jsonData) // Convert JSON data to a string and set it as the request body
            };

            fetch('/create_GOL', options);
            setInterval(updateGameState, 1000);
        }
    </script>
</body>
© www.soinside.com 2019 - 2024. All rights reserved.