Flask、Python、模板:是否可以将变量从“index”html 传递到“post”,而不使用“post”URL 中的变量?

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

背景

  • 主页包含帖子标题和副标题。它还包含指向单个“帖子”页面的链接。

  • 帖子页面包含标题、副标题和正文。

  • 使用请求响应构建主页和个人帖子页面,并使用 Flask 进行模板化。

  • 我试图将“requests.get”放入方法“def home()”中,以便每次加载主页时,它都会用新数据刷新。

蟒蛇:

from flask import Flask, render_template
import requests

app = Flask(__name__)


@app.route('/')
def home():
    r = requests.get("https://api.npoint.io/c790b4d5cab58020d391")
    data = r.json()
    print(data)
    return render_template("index.html", response_data=data)


@app.route("/URL/post/<num>")
def content(num):
    return render_template("post.html", title=title, subtitle=subtitle, body=body, num=num)


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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://fonts.googleapis.com/css2?family=Raleway" rel="stylesheet">
    <link rel="stylesheet" href="../static/css/styles.css">
</head>
<body>
<div class="wrapper">
    <div class="top">
        <div class="title"><h1>My Blog</h1></div>
    </div>
    {% for i in [0, response_data|length-1]: %}
        <div class="content">
            <div class="card">
                <h2>{{ response_data[i].title }}</h2>
                <p class="text">{{ response_data[i].subtitle }}</p>
                <a href = "{{ url_for('content', num=i, title=response_data[i].title, subtitle=response_data[i].subtitle, body=response_data[i].body) }}">Read</a>
            </div>
        </div>
    {% endfor %}
</div>
</body>
<footer>
    <p>Made with ♥️ in London.</p>
</footer>
</html>

post.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://fonts.googleapis.com/css2?family=Raleway" rel="stylesheet">
    <link rel="stylesheet" href="../static/css/styles.css">
</head>
<body>
<div class="wrapper">
    <div class="top">
        <div class="title"><h1>{{ title }}</h1></div>
           </div>
        <div class="content">
            <div class="card">
                <h2>{{ subtitle }}</h2>
                <p>{{ body }}</p>
            </div>

    </div>
</div>
</body>
<footer>
    <p>Made with ♥️ in London.</p>
</footer>
</html>
  • 我试图将“requests.get”放入方法“def home()”中,以便每次加载主页时,它都会用新数据刷新。

  • 但是,通过这种方式,响应数据被保存在 home() 函数内部。我需要访问各个帖子页面中相应的标题、副标题、正文、编号。

  • 我可以通过 ,因为帖子 URL 中需要它。但是,我不知道如何将标题,副标题,正文传递给子页面。

我的第一个问题是,如果我还想将标题、副标题和正文传递到单个帖子页面,以便可以呈现它,我该如何在不将这些信息添加到帖子 URL 的情况下做到这一点?

我的第二个问题是,将requests.get放在“def home()”中是正确的想法吗?比较将其放在主页之外的方法,我认为将其放在里面可以帮助每次加载时刷新主页内容,而不是重新加载 Flask 服务器。但如果我错了请纠正我。

我想知道,因为如果我把它放在 home() 函数之外,我就无法使用 response_data[num].title 来访问帖子页面中的数据,但直观上,用户会希望访问最新的数据当主页加载时,它应该在主页重新加载时刷新...

python html flask
1个回答
0
投票

第一个问题:如何将
title
subtitle
body
发送到单个帖子页面而不将它们包含在 URL 中?

是的,您可以将

title
subtitle
body
的所有数据传递到单个帖子页面,而无需使用服务器本身上的会话或临时存储将它们添加到 URL。

解决方案一:用Flask的
session

临时存储数据

您可以将

title
subtitle
body
存储在
session
中并显示在
/post/<num>
路由中,而无需在 URL 中传递它们。 以下是您的实施方式:

@app.route('/')
def home():
    r = requests.get("https://api.npoint.io/c790b4d5cab58020d391")
    data = r.json()
    session['post_data'] = data  # Store the data in the session
    return render_template("index.html", response_data=data)

现在,您可以从

content()
检索单个帖子页面的
session
路径中的信息,如下所示:

@app.route("/URL/post/<int:num>")
def content(num):
    # Get the stored data from the session
    post_data = session.get('post_data')
    # Access the post data based on 'num' as index
    if post_data and 0 <= num < len(post_data):
title = post_data[num]['title']
        subtitle = post_data[num]['subtitle']
        body = post_data[num]['body']
        return render_template("post.html", title=title, subtitle=subtitle, body=body)
    else:
        return "Post not found", 404

使用此解决方案,您不会将任何敏感数据泄露到 URL 中。

title
subtitle
body
的值安全地存储在会话中,然后传递到渲染模板
post.html

第二个问题:将
requests.get()
放入
home()
函数中只是为了刷新页面上的内容是否正确?

是的,如果您想在每次加载主页时获取新数据,那么在

requests.get()
内部调用
home()
确实有意义。每次用户访问主页时,都会向 API 发出新的请求,并且每次都会更新数据。

但是,有几件事需要考虑:

  • 性能:应用程序从主页向外部 API 发出的每个请求都可能会延迟响应(如果该 API 非常慢或无法访问)。在这种情况下,您可能需要实现缓存或优化 API 调用。
  • 缓存:由于数据不会经常更改,因此您可能希望将响应缓存一小段时间,例如 5 到 10 分钟,以便不进行过多的 API 调用,但仍保持数据新鲜。

您可以使用 Redis(仅限 linux/mac-os)或 Flask-Caching 来代替短期存储的数据,定期刷新而不是每次请求时刷新。

如果要使用 Flask-Caching 缓存数据,可以按如下方式存储缓存数据。以下是您的

home()
函数的外观:

from flask_caching import Cache

Configure cache
cache = Cache(app, config={'CACHE_TYPE': 'SimpleCache', 'CACHE_DEFAULT_TIMEOUT': 300})

@app.route('/')
@cache.cached()  # Cache the result for 5 minutes
def home():
    r = requests.get("https://api.npoint.io/c790b4d5cab58020d391")
    data = r.json()
    session['post_data'] = data
    return render_template("index.html", response_data=data)

这样,您就不必每次加载主页时都访问 API,但仍然会定期获取更新的数据。

结论

  • 要在不使用 URL 的情况下传递
    title
    subtitle
    body
    ,通过
    session
    存储和检索数据。
  • requests.get()
    放在
    home()
    里面就可以了。如果您希望每个请求都有新鲜数据,则尤其如此。但如果您多次调用 API,则需要考虑缓存,那么性能可能会成为一个严重的问题。

这应该可以解决您的问题,确保您在页面之间传递所需的数据,而不会使 URL 混乱,同时保持主页内容按照您的预期进行刷新。

© www.soinside.com 2019 - 2024. All rights reserved.