1

这是我的第一个网络应用程序“ChordMaster”。它基本上运行一个简单的乐谱编辑器,最后,您可以打印一个 pdf 文件。它在本地使用 Flask、Flask Session、Javascript、SQLAlchmy 等运行良好......但是当它部署在应用程序引擎(谷歌云平台)上时,返回的 render_template() 似乎不能正常工作:它没有传递正确的 html 页面和/或值。由于我在 Flask Session 的每个页面上都使用了@login_required,所以当用户 POST 时可能会丢失一些东西,但无法找出问题所在。非常感谢你们的帮助。

您可以查看部署的应用程序: https ://chordmaster-279503.ts.r.appspot.com/login

下面是显示第一页“索引”的代码的开头:

非常感谢,

import os
import datetime
import requests
import pymysql
import sqlalchemy

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, MetaData, Sequence, asc, desc, update, DateTime
from sqlalchemy.sql import select, func

from flask import Flask, flash, jsonify, redirect, render_template, request, session
from flask_session import Session
from tempfile import mkdtemp
from werkzeug.exceptions import default_exceptions, HTTPException, InternalServerError
from werkzeug.security import check_password_hash, generate_password_hash

from helpers import apology, login_required

# Configure application
app = Flask(__name__)

# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True

# Connect to database
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_socket_dir = os.environ.get("DB_SOCKET_DIR", "/cloudsql")
cloud_sql_connection_name = os.environ["CLOUD_SQL_CONNECTION_NAME"]

engine = sqlalchemy.create_engine(
    sqlalchemy.engine.url.URL(
        drivername="mysql+pymysql",
        username=db_user, 
        password=db_pass,
        database=db_name, 
        query={
            "unix_socket": "{}/{}".format(
                db_socket_dir, 
                cloud_sql_connection_name) 
        }
    ),
)

# Defining metadata woth SQLAlchemy
metadata = MetaData()

# Ensure responses aren't cached
@app.after_request
def after_request(response):
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response

# Configure session to use filesystem (instead of signed cookies)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

################ INDEX #################
@app.route("/", methods=["GET", "POST"])
@login_required
def index():

    # Reflecting metadata 
    metadata = MetaData(bind=engine, reflect=True)
    song_list = metadata.tables["song_list"]
    song_modif = metadata.tables["song_modif"]

    # Go to the "Edit" menu to work on the selected song
    if request.method == "POST":

        # Set the time at the moment of the submission
        time = datetime.datetime.now()

        # Get the selected song from the user
        song_name = request.form.get("text")

        # Create a backlog table of all operations
        with engine.connect() as conn:

            # Insert new modif
            ins = song_modif.insert().values(user_id=session["user_id"], song_name=song_name, time=time)
            conn.execute(ins)

            # Select all the current chord/bar from the updated table
            s = song_modif.select().where(song_modif.c.user_id==session["user_id"]).order_by(song_modif.c.time.desc())
            song_name_list = conn.execute(s).fetchall()

            # Get the name of the current song
            song_name=song_name_list[0]['song_name']

            # Select all the current chord/bar from the updated table
            song_table = metadata.tables[song_name]
            sc = song_table.select().order_by(song_table.c.bar.asc())
            song_complete = conn.execute(sc).fetchall()

            # Create format arguments for the table in html
            new_line_dict = conn.execute(select([func.count(song_table.c.bar)])).fetchone()

        # Create format arguments for the table in html
        new_line = int(new_line_dict[0]) / 4

        return render_template("tabreader.html", song_name=song_name, song_complete=song_complete, new_line=new_line)
    else:
        # Return the list of song
        with engine.connect() as conn:
            s = song_list.select().where(song_list.c.user_id==session["user_id"]).order_by(song_list.c.time.desc())
            list_of_song = conn.execute(s).fetchall()

        return render_template("index.html", song_list=list_of_song)

    return render_template("index.html")
```



4

1 回答 1

1

默认情况下,该render_template()函数正在搜索名为templates(区分大小写)的文件夹。该templates文件夹内是您的 index.html(以及所有其他 HTML 文件)应该所在的位置。

正如python flask 的 Flask() 函数的文档中所提到的,在templates您的主要烧瓶引擎文件的最顶部实例化您的 Flask 应用程序时,可以重命名默认文件夹。例如,如果您不想要templates文件夹,则可以将其重命名为其他名称,例如“folder_that_has_html_files”

app = Flask(__name__, template_folder='folder_that_has_html_files')

于 2021-08-18T00:50:05.847 回答