世界杯预选赛亚洲区_高达世界杯 - fzxzyy.com

快速入门¶

- 19世界杯

快速入门¶

迫不及待地想开始使用?本页面有详细介绍。请先按照 安装 的说明安装 Flask 并设置项目。

一个最小的应用程序¶

一个最小的Flask程序看起来像这样:

from flask import Flask

app = Flask(__name__)

@app.route("/")

def hello_world():

return "

Hello, World!

"

所以这些代码做了什么?

首先,我们导入了 Flask 类。该类的一个实例将成为我们的 WSGI 应用。

接下来我们创建这个类的一个实例。第一个参数是程序模块或包的名称,这是必要的,以便 Flask 知道在哪里查找资源,例如模板和静态文件。 __name__ 是一个方便的方式,适用于大多数情况。

然后我们使用 route() 装饰器来告诉 Flask 哪个 URL 应该触发我们的函数。

该函数返回我们想要在用户浏览器中显示的内容。默认的内容类型是 HTML,因此字符串中的 HTML 将由浏览器显示。

将这个文件其保存为 hello.py 或类似的名称。不要将程序文件命名为 flask.py,因为这会与 Flask 本身冲突。

要运行该程序,请使用 flask 或 python -m flask 命令。您需要使用 --app 选项告诉 Flask 程序的位置。

$ flask --app hello run

* Serving Flask app 'hello'

* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)

查找应用程序的过程

作为一种快捷方式,如果文件名为 app.py 或 wsgi.py,则无需使用 --app。更多详情请参阅 命令行接口 。

这将启动一个非常简单的自带的服务器,它足以用于测试,但可能不适合在生产环境中使用。有关部署选项,请参阅 部署到生产环境 。

现在转到 http://127.0.0.1:5000/ ,您应该会看到您的 hello world 问候。

如果端口 5000 已被其他程序占用,当服务器尝试启动时,你会看到 OSError: [Errno 98] 或 OSError: [WinError 10013] 错误。有关如何处理此问题,请参阅 Address already in use 。

外部可见的服务器

如果你运行服务器,你会发现你只能从你自己的电脑访问它,而不能从网络上的任何其他电脑访问。这是默认设置,因为在调试模式下,应用程序的用户可以在你的电脑上执行任意 Python 代码。

如果您禁用了调试器或信任网络上的用户,则只需在命令行中添加 --host=0.0.0.0 即可使服务器公开可用:

$ flask run --host=0.0.0.0

这会告诉你的操作系统监听所有公共 IP。

调试模式¶

flask run 命令的功能远不止启动开发服务器。启用调试模式后,服务器会在代码更改时自动重新加载;如果请求过程中出现错误,则会在浏览器中显示交互式调试器。

警告

该调试器允许从浏览器执行任意 Python 代码。虽然它受密码保护,但仍然存在重大安全风险。请勿在生产环境中运行开发用服务器或调试器。

要启用调试模式,请使用 --debug 选项。

$ flask --app hello run --debug

* Serving Flask app 'hello'

* Debug mode: on

* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)

* Restarting with stat

* Debugger is active!

* Debugger PIN: nnn-nnn-nnn

另请参阅:

用于开发的服务器 和 命令行接口 来了解有关在调试模式下运行的信息。

调试程序错误 了解有关使用内置调试器和其他调试器的信息。

日志记录 和 处理程序错误 用于记录错误并显示漂亮的错误页面。

HTML转义¶

返回 HTML(Flask 中的默认响应类型)时,必须对输出中嵌入的任何用户提供的值进行转义,以防止注入攻击。稍后介绍的使用 Jinja 渲染的 HTML 模板将自动执行此操作。

此处所示的 escape() 可以手动使用。为了简洁起见,大多数示例中都省略了它,但您应始终注意如何处理不受信任的数据。

from markupsafe import escape

@app.route("/")

def hello(name):

return f"Hello, {escape(name)}!"

如果用户设法提交名称 ,则转义会导致其呈现为文本,而不是在用户的浏览器中运行脚本。

路径中的 从 URL 中捕获一个值并将其传递给视图函数。这些变量规则如下所述。

路径¶

现代 Web 应用程序使用有意义的 URL 来帮助用户。如果页面使用有意义的用户能够记住的URL,那么他们更有可能喜欢该页面并再次访问。

使用 route() 装饰器将函数绑定到 URL:

@app.route('/')

def index():

return 'Index Page'

@app.route('/hello')

def hello():

return 'Hello, World'

你还可以做更多!你可以使 URL 的某些部分动态化,并将多个规则附加到一个函数。

变量规则¶

您可以通过使用 ``标记部分URL来向其添加变量部分。然后,您的函数将接收“”作为参数。您也可以选择使用转换器来指定参数的类型,例如 ``.

from markupsafe import escape

@app.route('/user/')

def show_user_profile(username):

# show the user profile for that user

return f'User {escape(username)}'

@app.route('/post/')

def show_post(post_id):

# show the post with the given id, the id is an integer

return f'Post {post_id}'

@app.route('/path/')

def show_subpath(subpath):

# show the subpath after /path/

return f'Subpath {escape(subpath)}'

转换器类型:

string (字符串)

(默认)接受任何不带斜杠的文本

int (正整数)

接受正整数

float (浮点数)

接受正浮点数

path (路径)

与 string 类似,但也接受斜杠

uuid (唯一标识符)

接受 UUID 字符串

唯一的 URL / 重定向行为¶

以下两个规则在尾部斜杠的使用上有所不同。:

@app.route('/projects/')

def projects():

return 'The project page'

@app.route('/about')

def about():

return 'The about page'

projects 端点的规范 URL 末尾有一个斜杠。它类似于文件系统中的文件夹。如果您访问的 URL 末尾没有斜杠(/projects),Flask 会将您重定向到末尾带有斜杠的规范 URL (/projects/)。

about 端点的规范 URL 没有尾部斜杠。它类似于文件的路径名。访问带有尾部斜杠的 URL(“/about/”)会产生 404 "Not Found"错误。这有助于保持这些资源的 URL 唯一,从而帮助搜索引擎避免对同一页面进行两次索引。

构建URL¶

要构建指向特定函数的 URL,请使用 url_for() 函数。它接受函数名称作为其第一个参数,以及任意数量的参数,每个参数对应于 URL 规则的一个变量部分。未知的变量部分将作为查询参数附加到 URL 中。

为什么要使用函数 url_for() 来构建 URL,而不是将它们硬编码到模板中?

使用函数 url_for() 通常比硬编码 URL 更具描述性 。

您可以一次性更改 URL,而不需要手动去更改硬编码的 URL。

URL 构建透明地处理特殊字符的转义。

生成的路径始终是绝对路径,避免了在浏览器中相对路径的意外行为。

如果您的应用程序被放置在 URL 根目录之外,例如,在 /myapplication 而不是 /, url_for() 会为您正确处理。

例如,这里我们使用 test_request_context() 方法来测试 url_for() 。 test_request_context() 会告诉 Flask 即使在使用 Python shell 时也要像在处理请求一样运行。参见 上下文局部变量 。

from flask import url_for

@app.route('/')

def index():

return 'index'

@app.route('/login')

def login():

return 'login'

@app.route('/user/')

def profile(username):

return f'{username}\'s profile'

with app.test_request_context():

print(url_for('index'))

print(url_for('login'))

print(url_for('login', next='/'))

print(url_for('profile', username='John Doe'))

/

/login

/login?next=/

/user/John%20Doe

HTTP 方法¶

Web 应用程序在访问 URL 时使用不同的 HTTP 方法。在使用 Flask 时,您应该熟悉这些 HTTP 方法。默认情况下,一个路径仅响应 GET 请求。您可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法。:

from flask import request

@app.route('/login', methods=['GET', 'POST'])

def login():

if request.method == 'POST':

return do_the_login()

else:

return show_the_login_form()

上面的示例将路径的所有HTTP方法保存在一个函数中,如果每个部分都要使用一些公共数据,这将很有用。

您还可以将不同方法的视图分离到不同的函数中。Flask 提供了适用于每种常见的 HTTP 方法的函数 get()、post() 等来装饰这些路径的快捷方式。

@app.get('/login')

def login_get():

return show_the_login_form()

@app.post('/login')

def login_post():

return do_the_login()

如果存在 GET,Flask 会自动添加对 HEAD 方法的支持,并根据 HTTP RFC 处理 HEAD 请求。同样,OPTIONS 也会自动为您实现。

静态文件¶

动态 Web 应用程序也需要静态文件。CSS 和 JavaScript 文件通常就来自它们。理想情况下,您的 Web 服务器已配置为提供这些文件,但在开发过程中,Flask 也可以做到这一点。只需在您的包中或模块旁边创建一个名为 static 的文件夹,它就可以在应用程序的 /static 目录下找到。

要生成静态文件的 URL,请使用特殊的 'static' 端点名称:

url_for('static', filename='style.css')

该文件必须作为 static/style.css 存储在文件系统中。

渲染模板¶

在 Python 中生成 HTML 并不好玩,实际上相当繁琐,因为你必须自己进行 HTML 转义才能保证应用程序的安全。因此,Flask 会自动为你配置 Jinja2 模板引擎。

模板可用于生成任何类型的文本文件。对于 Web 应用程序,您会主要生成 HTML 页面,但您也可以生成 Markdown 文件、电子邮件的文本以及其他任何内容。

有关 HTML、CSS 和其他 Web API 的参考,请使用 MDN Web Docs.

要渲染模板,您可以使用 render_template() 方法。您只需提供模板名称以及要作为关键字参数传递给模板引擎的变量即可。以下是如何渲染模板的简单示例:

from flask import render_template

@app.route('/hello/')

@app.route('/hello/')

def hello(name=None):

return render_template('hello.html', person=name)

Flask 会在 templates 文件夹中查找模板。如果你的应用是一个模块,那么这个文件夹就位于模块旁边;如果你的应用是一个包,那么它实际上位于包内部:

情况 1: 一个模块:

/application.py

/templates

/hello.html

情况 2: 一个包:

/application

/__init__.py

/templates

/hello.html

对于模板,您可以充分利用 Jinja2 模板的全部功能。更多信息,请访问官方的 Jinja2 模板文档 .

以下是一个示例模板:

Hello from Flask

{% if person %}

Hello {{ person }}!

{% else %}

Hello, World!

{% endif %}

在模板内部,您还可以访问 config, request, session 和 g [1] 对象以及:func:~flask.url_for 和 get_flashed_messages() 函数。

如果使用继承,模板会特别有用。如果你想了解它的工作原理,请参阅 模板继承 。基本上,模板继承使得在每个页面上保留某些元素(例如页眉、导航和页脚)成为可能。

转义已自动启用,因此如果 person 包含 HTML,它将被自动转义。如果您信任某个变量,并且您知道它是安全的 HTML(例如,因为它来自将 wiki 标记语言转换为 HTML 的模块),您可以使用 Markup 类或使用模板中的 |safe 过滤器将其标记为安全。更多示例,请参阅 Jinja 2 文档。

以下是对 Markup 类工作原理的基本介绍:

>>> from markupsafe import Markup

>>> Markup('Hello %s!') % 'hacker'

Markup('Hello <blink>hacker</blink>!')

>>> Markup.escape('hacker')

Markup('<blink>hacker</blink>')

>>> Markup('Marked up » HTML').striptags()

'Marked up » HTML'

Changelog

在 0.5 版本发生变更: 自动转义功能不再对所有模板启用。仅以下模板扩展名会触发自动转义: .html, .htm, .xml, .xhtml . 从字符串加载的模板将被禁用自动转义。

[1]

不确定 g 对象是什么?它是一个可以用来存储您所需信息的东西。请参阅 flask.g 和 在Flask中使用SQLite3 数据库 的文档。

访问请求数据¶

对于 Web 应用来说,响应客户端发送到服务器的数据至关重要。在 Flask 中,这些信息由全局的 request 对象提供。如果您有使用 Python 的经验,您可能会好奇这个对象怎么能是全局的,以及 Flask 是如何做到多线程安全的。答案是上下文局部变量:

上下文局部变量¶

内部信息

如果您想了解其工作原理以及如何使用上下文局部变量实现测试,请阅读本节,否则请跳过它。

Flask 中的某些对象是全局对象,但并非通常意义上的全局对象。这些对象实际上是特定上下文中局部对象的代理。听起来有点拗口,但其实很容易理解。

想象一下,上下文就是在处理请求的线程。一个请求到来,Web 服务器决定创建一个新线程(或者能够处理除线程之外的并发系统的其他底层对象)。当 Flask 启动其内部请求处理时,它会判断当前线程是活动上下文,并将当前应用程序和 WSGI 环境绑定到该上下文(线程)。它以一种智能的方式执行此操作,以便一个应用程序可以调用另一个应用程序而不会中断。

那么这对你意味着什么?基本上,除非你正在进行单元测试之类的工作,否则你完全可以忽略这种情况。你会注意到,依赖于请求对象的代码会突然出错,因为没有请求对象。解决方案是自己创建一个请求对象并将其绑定到上下文。单元测试最简单的解决方案是使用 test_request_context`上下文管理器。结合 ``with`() 语句,它会绑定一个测试用请求,以便你能够与其交互。以下是一个例子:

from flask import request

with app.test_request_context('/hello', method='POST'):

# now you can do something with the request until the

# end of the with block, such as basic assertions:

assert request.path == '/hello'

assert request.method == 'POST'

另一种可能性是将整个 WSGI 环境传递给 request_context() 方法:

with app.request_context(environ):

assert request.method == 'POST'

请求对象¶

请求对象已在 API 部分中记录,我们在此不再赘述(参见 Request )。以下是对一些最常见操作的概述。首先,您需要从 flask 模块导入它:

from flask import request

当前的请求方法可以通过 method 属性获取。要访问表单数据(通过 POST 或 PUT 请求传输的数据),可以使用 form 属性。以下是上述两个属性的完整示例:

@app.route('/login', methods=['POST', 'GET'])

def login():

error = None

if request.method == 'POST':

if valid_login(request.form['username'],

request.form['password']):

return log_the_user_in(request.form['username'])

else:

error = 'Invalid username/password'

# the code below is executed if the request method

# was GET or the credentials were invalid

return render_template('login.html', error=error)

如果 form 属性中不存在该键,会发生什么情况?在这种情况下,会引发一个特殊的 KeyError 错误。您可以像捕获正常 KeyError 错误一样捕获它,但如果不这样做,则会显示 HTTP 400 Bad Request 错误页面。因此,在很多情况下,您无需处理这个问题。

要访问 URL 中提交的参数(?key=value),您可以使用 args 属性:

searchword = request.args.get('key', '')

我们建议使用 get 或捕获 KeyError 来访问 URL 参数,因为用户可能会更改 URL,在这种情况下向他们显示 400 错误请求页面并不方便用户使用。

有关请求对象的方法和属性的完整列出,请转到 Request 文档。

文件上传¶

你可以使用 Flask 轻松处理上传的文件。只需确保不要忘记在 HTML 表单上设置 enctype="multipart/form-data" 属性,否则浏览器将根本不会传输你的文件。

上传的文件存储在内存中或文件系统的一个临时位置。您可以通过查看请求对象上的 files 属性来访问这些文件。每个上传的文件都存储在该字典中。它的行为类似于标准的 Python file 对象,但它还具有一个 save() 方法,允许您将该文件存储在服务器的文件系统上。以下是一个简单的示例,展示了它的工作原理:

from flask import request

@app.route('/upload', methods=['GET', 'POST'])

def upload_file():

if request.method == 'POST':

f = request.files['the_file']

f.save('/var/www/uploads/uploaded_file.txt')

...

如果您想知道文件在上传到你的应用程序之前在客户端是如何命名的,可以访问 filename 属性。但请记住,此值可以被伪造,所以永远不要相信它。如果您想使用客户端的文件名将文件存储在服务器上,请将其传递给 Werkzeug 提供的 secure_filename() 函数:

from werkzeug.utils import secure_filename

@app.route('/upload', methods=['GET', 'POST'])

def upload_file():

if request.method == 'POST':

file = request.files['the_file']

file.save(f"/var/www/uploads/{secure_filename(file.filename)}")

...

要查看一些更好的示例,请参阅 上传文件.

浏览器 Cookies¶

要访问 Cookie,您可以使用 cookies 属性。要设置 Cookie,您可以使用响应对象的 set_cookie 方法。请求对象的 cookies 属性是一个字典,其中包含用户端传输的所有 Cookie。如果您想使用sessions,请不要直接使用 Cookie,而是使用 Flask 中的 会话 ,它会在 Cookie 的基础上为您增加一些安全性。

读取 Cookies:

from flask import request

@app.route('/')

def index():

username = request.cookies.get('username')

# use cookies.get(key) instead of cookies[key] to not get a

# KeyError if the cookie is missing.

存储 Cookies:

from flask import make_response

@app.route('/')

def index():

resp = make_response(render_template(...))

resp.set_cookie('username', 'the username')

return resp

请注意,Cookie 是设置在响应对象上的。由于您通常只是从视图函数返回字符串,因此 Flask 会将它们转换为响应对象。如果您想要显式地这样做,可以使用 make_response() 函数,然后对其进行修改。

有时你可能想在响应对象尚不存在时设置 cookie。这可以通过使用 延迟执行的请求回调 模式来实现。

另请参阅 关于响应 。

重定向和错误¶

要将用户重定向到另一个端点,请使用 redirect() 函数;要带着一个错误代码提前中止请求,请使用 abort() 函数:

from flask import abort, redirect, url_for

@app.route('/')

def index():

return redirect(url_for('login'))

@app.route('/login')

def login():

abort(401)

this_is_never_executed()

这是一个毫无意义的例子,因为用户将从索引被重定向到一个他们无法访问的页面(401 表示拒绝访问),但它展示了其工作原理。

默认情况下,每个错误代码都会显示一个黑白的错误页面。如果要自定义错误页面,可以使用 errorhandler() 装饰器:

from flask import render_template

@app.errorhandler(404)

def page_not_found(error):

return render_template('page_not_found.html'), 404

注意 render_template() 调用后面的 404 。这告诉 Flask 该页面的状态码应该是 404,表示未找到。默认情况下,状态码为 200,翻译过来就是:一切顺利。

请参阅 处理程序错误 以了解更多详细信息。

关于响应¶

视图函数的返回值会自动转换为响应对象。如果返回值是字符串,则会转换为一个包含字符串作为响应主体、 200 OK 状态码和 text/html MIME 类型的响应对象。如果返回值是字典或列表,则会调用 jsonify() 来生成响应。Flask 将返回值转换为响应对象的逻辑如下:

如果返回了类型正确的响应对象,则它将直接从视图返回。

如果它是一个字符串,则使用该数据和默认参数创建一个响应对象。

如果它是一个返回字符串或bytes的迭代器或生成器,则它将被视为流响应。

如果它是一个字典或列表,则使用 jsonify() 创建一个响应对象。

如果返回的是元组,则元组中的项可以提供额外的信息。此类元组的格式必须为 (response, status), (response, headers), 或 (response, status, headers) 。 status 值将覆盖状态码, headers 可以是包含附加HTTP标头值的列表或字典。

如果这些都不符合,Flask 将假定返回值是一个有效的 WSGI 应用程序并将其转换为响应对象。

如果您想要在视图中获取响应对象的结果,您可以使用 make_response() 函数。

想象一下你有一个这样的视图函数:

from flask import render_template

@app.errorhandler(404)

def not_found(error):

return render_template('error.html'), 404

您只需要用 make_response() 包装返回表达式然后获取响应对象来修改它,最后返回它:

from flask import make_response

@app.errorhandler(404)

def not_found(error):

resp = make_response(render_template('error.html'), 404)

resp.headers['X-Something'] = 'A value'

return resp

JSON 格式的 API¶

编写 API 时,JSON 是一种常见的响应格式。使用 Flask 编写这样的 API 非常简单。如果你从视图返回一个 dict 或 list ,它将被转换为 JSON 响应。

@app.route("/me")

def me_api():

user = get_current_user()

return {

"username": user.username,

"theme": user.theme,

"image": url_for("user_image", filename=user.image),

}

@app.route("/users")

def users_api():

users = get_all_users()

return [user.to_json() for user in users]

这是将数据传递给 jsonify() 函数的快捷方式,该函数将序列化任何支持的 JSON 数据类型。这意味着字典或列表中的所有数据都必须是可 JSON 序列化的。

对于数据库模型等复杂类型,您需要先使用序列化库将数据转换为有效的 JSON 类型。Flask 社区维护着许多序列化库和 Flask API 扩展,它们支持更复杂的应用程序。

会话¶

除了请求对象之外,还有一个名为 session 的对象,它允许你在几个请求间存储特定于用户的信息。它基于 cookie 实现,并对 cookie 进行加密签名。这意味着用户可以查看你的 cookie 内容,但无法修改,除非他们知道用于签名的密钥。

要使用sessions,您必须设置一个密钥。session的工作原理如下:

from flask import session

# Set the secret key to some random bytes. Keep this really secret!

app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')

def index():

if 'username' in session:

return f'Logged in as {session["username"]}'

return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])

def login():

if request.method == 'POST':

session['username'] = request.form['username']

return redirect(url_for('index'))

return '''

'''

@app.route('/logout')

def logout():

# remove the username from the session if it's there

session.pop('username', None)

return redirect(url_for('index'))

如何生成好的密钥

密钥应该尽可能随机。你的操作系统有办法基于加密随机生成器生成相当随机的数据。使用以下命令可以快速生成用于 Flask.secret_key (或 SECRET_KEY)的值:

$ python -c 'import secrets; print(secrets.token_hex())'

'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'

关于基于 Cookie 的sessions的注意事项:Flask 会将您传入session对象的值序列化为 Cookie。如果您发现某些值在请求之间无法保持,且 Cookie 确实已启用,而您没有收到清晰的错误消息,请检查页面响应中 Cookie 的大小,并将其与 Web 浏览器支持的大小进行比较。

除了默认的基于用户端的sessions之外,如果您想在服务器端处理sessions,有几个 Flask 扩展可以支持此功能。

消息闪现¶

好的应用程序和用户界面都离不开反馈。如果用户得不到足够的反馈,他们最终可能会讨厌这个应用程序。Flask 的消息闪现系统提供了一种非常简单的方法来向用户提供反馈。消息闪现系统基本上是在一次请求末尾中存储消息,并在下一次请求中显示的机制。这通常与布局模板结合使用来显示消息。

要闪现消息,请使用 flash() 方法;要获取消息,可以使用 get_flashed_messages() 方法,该方法在模板中也可用。完整示例请参阅 消息闪现 。

日志记录¶

Changelog

Added in version 0.3.

有时您可能会遇到这样的情况:您处理的数据应该正确,但实际上却不正确。例如,您可能有一些用户端代码向服务器发送 HTTP 请求,但该请求显然格式错误。这可能是由于用户篡改了数据,或者用户端代码出现故障造成的。大多数情况下,在这种情况下回复 400 Bad Request 是可以的,但有时这样做是不行的,代码必须继续工作。

你可能仍然想记录下有一些可疑的事情发生。这时,记录器就派上用场了。从 Flask 0.3 开始会预配置一个记录器供你使用。

以下是一些日志调用示例:

app.logger.debug('A value for debugging')

app.logger.warning('A warning occurred (%d apples)', 42)

app.logger.error('An error occurred')

附加的 logger 是一个标准日志记录器 Logger,因此请转到官方 logging 文档以获取更多信息。

参见 处理程序错误 。

添加WSGI中间件¶

要将 WSGI 中间件添加到 Flask 应用,请包装应用的 wsgi_app 属性。例如,要应用 Werkzeug 的 ProxyFix 中间件来在 Nginx 后运行:

from werkzeug.middleware.proxy_fix import ProxyFix

app.wsgi_app = ProxyFix(app.wsgi_app)

包装 app.wsgi_app 而不是 app 意味着 app 仍然指向您的Flask应用程序,而不是中间件,因此您可以继续直接使用和配置 app 。

使用 Flask 扩展¶

扩展是一些可帮助您完成常见任务的软件包。例如,Flask-SQLAlchemy 提供了 SQLAlchemy 支持,让您能够轻松便捷地将其与 Flask 配合使用。

有关 Flask 扩展的更多信息,请参阅 扩展 。

部署到 Web 服务器¶

准备好部署你的新 Flask 应用了吗?请参阅 部署到生产环境 。

如何区分中央空调进风口和出风口
小号福利:7.3全十二职业随从推荐搭配分享