问:我想我在视频中途迷路了。在定义 get_saved_data() 方法之前,一切都很好。之后,我就是无法理解整个过程的流程。教师在使用之前没有解释他在视频中使用的东西也无济于事。这对他来说当然很明显,因为他知道这些东西,但是对于 Flask 的初学者来说,这一切都不需要那么明显。
例如 - 为什么 get_saved_data() 在 save() 方法中被调用?我的意思是我知道这是为了让您拥有最新的数据,但是为什么这个例子需要它?然后对数据调用 update() 方法。这样做的目的是什么?同样,我知道 update() 会更改 dict 的值以更新传入的 dict 的值,但为什么在本示例中需要这样做?无论如何,您总是显示最新的“cookie”值,对吗?你不能在熊的东西下的表单中显示多个 cookie。
此外,还有突然出现的 saves 变量。那有什么必要?
我试图用注释跟踪代码并放一些 ? 在我没有完全掌握的地方做标记(包括上面的问题)。
from flask import Flask
from flask import render_template, redirect, url_for, json, make_response, request
app = Flask(__name__)
def get_saved_data():
try:
#json.loads 接受一个 JSON 字符串并把它变成“Python 对象???”
data = json.loads(request.cookies.get('character'))
except TypeError:
data = {}
return data
# 主页路由
@app.route('/')
def index():
# 这个视图在什么时候被调用请求来自主页 /
# get_saved_data() 被调用以查找任何保存的数据,在这种情况下,是 cookie
data = get_saved_data()
# 如果没有保存任何内容,则返回一个空字典并将其存储在保存变量中
# 在 index.html 中,显示键 'name'(cookie)的值 - 如果没有设置则为空白
return render_template("index.html ", saves=data)
@app.route('/save', methods=['POST'])
def save():
"""
这个方法作为用户提交表单时的处理程序调用,
方法保存用户输入的数据设置 cookie
"""
response = make_response(redirect(url_for('index')))
# 加载现有保存的数据
data = get_saved_data()
# 用新值更新当前 dict ???
data.update(dict(request.form.items()))
# 将名为 'character' 的 cookie 的值设置为用户在表单中输入的值
response.set_cookie('character', json.dumps(dict(request.form.items())))
# 返回显示给用户的响应
return响应
app.run(debug=True, host='0.0.0.0', port=8000)
答:让我们从回顾一些概念开始。
当浏览器请求一个网页时,flask 创建一个request对象:
来自 URL 查询数据的数据(URL 中“?”后的项目):存储在 request.args
来自提交表单的数据:存储在 request.form
来自先前设置的 cookie 的数据:存储在 request.cookie
从浏览器接收到的所有 cookie 数据都可以在request.cookie. 发送到浏览器的所有 cookie 数据都作为属性添加到response
一开始没有cookie数据,request.cookie是空的。任何 cookie 数据(如果存在)都会在每次请求时从浏览器接收。
作为预防措施,由于我们无法提前知道浏览器中是否设置了当前 cookie(来自其他页面视图,或其他未来添加的视图代码),因此最好将新 cookie 的任何数据与当前 cookie 合并从浏览器接收。如果没有这种合并,我们可能会意外地清除我们不知道的 cookie,而不是将它们发送回浏览器。
get_saved_data()创建了一个辅助函数来从当前请求的 cookie 中提取数据。(一个更好的名字可能是get_received_cookie_data())。Cookie 数据作为 JSON 字符串接收。该函数json.loads将此字符串转换为 python 字典。
在 index() 视图中,get_saved_data()用于帮助index.html使用任何存在的 cookie 数据填充模板。
在 save() 视图中,从浏览器接收到的表单数据将作为 cookie 发送回浏览器。第一步是使用get_saved_data()获取当前从浏览器接收到的 cookie 数据并将其放入 dict 中data。
这data.update()是一种用另一个字典的内容更新一个字典的奇特方式。否则,我们需要遍历表单数据并将每个键/值对添加到data字典中。此时,data具有来自当前 cookie 和表单数据的合并值。最后一个任务是将合并的 cookie 数据返回到浏览器。
继续在save()视图中,从服务器发送的响应将是redirect(HTTP 状态代码 302),它将对浏览器说:“再次询问此页面,但使用 URL 'index' 代替”。我们捎带要在此响应中发送的任何 cookie 数据。cookie 数据是通过使用转换data为字符串json.dumps()并使用将其添加为属性来准备的response.set_cookie。
当浏览器收到带有捎带 cookie 数据的“302”响应时,它会保存 cookie,然后将新请求重新提交到“/index”,包括最新的(刚刚保存的)cookie。
返回index()视图,使用最新 cookie 接收到的这个新请求用于填充“index.html”模板。函数的saves=data一部分render_template,将datadict分配给上下文变量“saves”。此上下文变量在“index.html”模板中访问,{{ saves.get(....) }}用于从字典中提取值并将它们显示在模板中。