Flask 入门教程

这篇具有很好参考价值的文章主要介绍了Flask 入门教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QuickStart

1.安装

https://flask.palletsprojects.com/en/2.3.x/installation/

 conda install flask

2.flask 应用示例

  1. import flask
  2. 创建 flask 对象,构造参数是应用的包名
  3. route 是告诉 flask,URL 触发函数
  4. 函数返回想要在浏览器中显示的信息,默认是 html
  5. 调用 app.run 启动应用

代码:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

if __name__ == '__main__':
        app.run(host="127.0.0.1", port="5200")

结果:
Flask 入门教程,flask,python,后端
端口冲突:
OSError: [Errno 98] 或者 OSError: [WinError 10013]

开发

1.路由(Routing)

现代web应用可以通过有意义的路由来绑定页面,帮助用户

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, World'
请求方法(Http Method)

flask 可以指定路由函数的访问方法,默认是 Get

  • 指定单个路由的多个方法
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()
  • 指定单个路由的单个方法
@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 请求。

变量规则

可以通过使用<variable_name>标记区段来向URL添加可变区段。
然后,函数接收<variable_name>作为关键字参数。
还可以选择使用转换器来指定参数的类型,例如converter:variable_name。

from markupsafe import escape

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return f'User {escape(username)}'

@app.route('/post/<int:post_id>')
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/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {escape(subpath)}'
string (default) accepts any text without a slash
int accepts positive integers
float accepts positive floating point values
path like string but also accepts slashes
uuid accepts UUID strings
末尾正斜杠

下文代码中两个路由的区别在于末尾正斜杠
对于 @app.route(‘/projects/’),若访问 /projects 会自动重定向到 /projects/
对于 @app.route(‘/about’),若 /about/ 不会重定向到 /about ,更具有唯一性

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'
Url 构造

使用 url_for 构造指向特定函数的URL,它接受函数名作为第一个参数和任意数量的关键字参数,每个参数对应于URL规则的一个变量部分。未知变量部分作为查询参数追加到URL。

  1. url_for 通常比硬编码 url 更具描述性。
  2. 一次性更改url,而无需手动更改硬编码的url
  3. URL构建透明地处理特殊字符的转义
  4. 生成的路径总是绝对的,避免了浏览器中相对路径的意外行为
  5. 如果应用程序位于URL根目录之外,例如,在/myapplication中而不是/中,url_for()将正确地执行给你

代码:

from flask import url_for

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

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
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

2.HTML渲染

从 Python 内部生成相当麻烦,因为您必须自己进行HTML转义以保证应用程序的安全。
因此,Flask 会自动为您配置 Jinja2 模板引擎。模板可用于生成任何类型的文本文件。对于 web 应用程序,您将主要生成 HTML 页面,但您也可以生成标记,电子邮件的纯文本和其他任何内容。
https://jinja.palletsprojects.com/en/3.1.x/templates/
有关 HTML、CSS 和其他 web api 的参考,请参阅 MDN web Docs。
https://developer.mozilla.org/zh-CN/
要渲染模板,你可以使用 render_template() 方法。您所要做的就是提供模板的名称和要作为关键字参数传递给模板引擎的变量。下面是一个如何渲染模板的简单示例:

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

render_template 会自动渲染 hello.html,如果 hello.html 在对应的 templates 文件夹下

  1. 文件
/application.py
/templates
    /hello.html
/application
    /__init__.py
    /templates
        /hello.html

在模板内部,您还可以访问配置、请求、会话和 gil 对象以及url_for()和 get_flashd_messages() 函数。模板在使用继承时特别有用。如果你想知道它是如何工作的,请参阅模板继承。https://flask.palletsprojects.com/en/2.3.x/patterns/templateinheritance/
基本上,模板继承使得在每个页面上保留某些元素 (如页眉、导航和页脚) 成为可能。
自动转义是启用的,所以如果 name 包含 HTML,它将自动转义。如果您可以信任一个变量,并且您知道它将是安全的 HTML(例如,因为它来自将wiki标记转换为HTML的模块),您可以通过使用markup类或在模板中使用Isafe过滤器将其标记为安全。查看Jinja 2文档了解更多示例。下面是对Markup类工作原理的基本介绍:

from markupsafe import Markup
Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup('<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
Markup.escape('<blink>hacker</blink>')
Markup('&lt;blink&gt;hacker&lt;/blink&gt;')
Markup('<em>Marked up</em> &raquo; HTML').striptags()
'Marked up » HTML'

3.获取请求参数(Accessing Request Data)

对于web应用程序,对客户端发送到服务器的数据做出响应是至关重要的。在Flask中,这个信息由全局请求对象提供。如果你有一些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'
请求对象(The Request Object)
获取 query params 参数

通过 request 对象获取传递参数
https://flask.palletsprojects.com/en/2.3.x/api/#flask.Request

from flask import request

@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)

使用 request.args.get() 会自动捕获 error,不需要手动捕获 error

searchword = request.args.get('key', '')
获取 json 参数

通过 request 对象获取传递的 json 参数

from flask import request

@app.route('/login', methods=['POST', 'GET'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.json['username'],
                       request.json['password']):
            return log_the_user_in(request.json['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)
文件上传到 falsk

https://flask.palletsprojects.com/en/2.3.x/patterns/fileuploads/
你可以用Flask轻松地处理上传的文件。只要确保不要忘记在HTML表单上设置 “multipart/form-data” 属性,否则浏览器根本不会传输你的文件。
上传的文件存储在内存中或文件系统上的临时位置。您可以通过查看请求对象上的 files 属性来访问这些文件。每个上传的文件都存储在该字典中。它的行为就像一个标准的Python文件对象,但它也有一个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,可以使用cookie属性。要设置cookie,可以使用响应对象的set_cookie方法。请求对象的cookie属性是一个包含客户端传输的所有cookie的字典。如果你想使用会话,不要直接使用cookie,而是使用Flask中的会话,它为你在cookie上添加了一些安全性。
获取 cookie 参数

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.

设置 cookie 参数

from flask import make_response

@app.route('/')
def index():
    resp = make_response(render_template(...))
    resp.set_cookie('username', 'the username')
    return resp

4.重定向和错误页

要将用户重定向到另一个端点,请使用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

5.响应(Response)

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

  1. 如果返回了正确类型的响应对象,它将直接从函数返回。
  2. 如果是字符串,则使用该数据和默认参数创建响应对象。
  3. 如果它是返回字符串或字节的迭代器或生成器,则将其视为流响应。
  4. 如果它是一个字典或列表,则使用 jsonify() 创建响应对象。
  5. 如果返回元组,则元组中的项可以提供额外的信息。这样的元组必须采用(response, status)、(response, headers) 或 (response, status, headers) 的形式。状态值将覆盖状态码,报头可以是附加报头值的列表或字典。
  6. 如果这些都不起作用,Flask将假定返回值是一个有效的WSGI应用程序,并将其转换为响应对象。
make_response

可以使用 make_response 自己构造 response
https://flask.palletsprojects.com/en/2.3.x/api/#flask.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时,常见的响应格式是JSON。用Flask编写这样的API很容易。如果从视图返回字典或列表,它将被转换为json响应。
这是将数据传递给jsonify()函数的快捷方式,该函数将序列化任何受支持的JSON数据类型。这意味着字典或列表中的所有数据必须是JSON可序列化的。对于复杂类型(如数据库模型),您需要首先使用序列化库将数据转换为有效的JSON类型。社区维护了许多序列化库和Flask API扩展,以支持更复杂的应用程序。

@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]

6.静态文件

动态web应用程序也需要静态文件。这通常是 CSS 和 JavaScript 文件的来源。
理想情况下,您的 web 服务器被配置为为您服务,但在开发期间 Flask 也可以做到这一点。
只需在包中或模块旁边创建一个名为 static 的文件夹,它将在应用程序的 /static 处可用。要为静态文件生成 url,使用特殊的 static 端点名称:

// 文件需要方法 static 文件夹下
url_for('static', filename='style.css')

7.会话

除了请求对象之外,还有第二个对象称为session,它允许您从一个请求到下一个请求存储特定于用户的信息。这是在 cookie 之上实现的,并对 cookie 进行加密签名。这意味着用户可以查看 cookie 的内容,但不能修改它,除非他们知道用于签名的秘密密钥。为了使用会话,您必须设置一个密钥。以下是会话的工作原理:

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 '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@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:

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

关于基于cookie的会话的注意事项:Flask将获取您放入会话对象中的值并将其序列化到cookie中。如果你发现一些值不能在请求中持续存在,cookie确实是启用的,并且你没有得到一个明确的错误信息,那么请检查你的页面响应中cookie的大小,并将其与web浏览器支持的大小进行比较。

8.日志

有时您可能会遇到这样的情况:您处理的数据应该是正确的,但实际上并非如此。例如,您可能有一些向服务器发送HTTP请求的客户端代码,但它显然是错误的。这可能是由用户引起的篡改数据,或客户端代码失败。大多数情况下,在这种情况下回复 400 错误请求是可以的,但有时这行不通,代码必须继续工作。你可能仍然想记录一些可疑的事情发生了。这就是日志派上用场的地方。从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')

9.HTML转义

由于返回值的默认类型是HTML,所以为了防止被用户注入,所以用户传递的参数在返回值中必须被转义
方法为使用 escape 函数
代码:

from flask import Flask, request
from markupsafe import escape

app = Flask(__name__)

@app.route("/name")
def hello():
    name = request.json['name']
    return f"Hello, {escape(name)}!"

if __name__ == '__main__':
    app.run(host="127.0.0.1", port="5200", debug=True)

测试:
注入一段 alter(“bad”) 的代码
Flask 入门教程,flask,python,后端
若没有通过转义:
会触发注入代码
Flask 入门教程,flask,python,后端
若通过转义:
注入代码会被转义成字符串
Flask 入门教程,flask,python,后端

10.调试模式

  • 代码发生修改,会自动重启服务
  • 报错时,浏览器会显示报错堆栈信息,并可以调试

代码:
Flask 入门教程,flask,python,后端
调试模式:
Flask 入门教程,flask,python,后端
报错堆栈:
Flask 入门教程,flask,python,后端

11.Message Flashing

Flask提供了一种非常简单的方法,通过闪烁系统向用户提供反馈。闪烁系统基本上使得在请求结束时记录消息并在下一个(且仅下一个)请求时访问它成为可能。这通常与一个布局模板相结合,以公开消息。
https://flask.palletsprojects.com/en/2.3.x/patterns/flashing/

12.部署到生产环境

https://flask.palletsprojects.com/en/2.3.x/deploying/#deploying-to-production

13.Hooking in WSGI Middleware

要将WSGI中间件添加到Flask应用程序中,请包装应用程序的wsgi_app属性。例如,要应用Werkzeug的ProxyFix中间件运行在Nginx之后:
https://werkzeug.palletsprojects.com/en/2.3.x/middleware/proxy_fix/#werkzeug.middleware.proxy_fix.ProxyFix

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

14.Using Flask Extensions

https://flask.palletsprojects.com/en/2.3.x/extensions/文章来源地址https://www.toymoban.com/news/detail-731802.html

到了这里,关于Flask 入门教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flask入门教程(非常详细),从零基础入门到精通,看完这一篇就够了

    目录 Flask入门 运行方式 URL与函数的映射(动态路由) PostMan的使用 查询参数的获取 上传文件 其它参数 url_for 函数 响应-重定向 响应-响应内容 响应-自定义响应 Flask模板 模板介绍 模板的使用 模板-传参 模板使用url_for函数 过滤器介绍 Jinja模板自带过滤器 流程控制-选择结构 流程

    2024年02月05日
    浏览(75)
  • Python - flask后端开发笔记

    ​ Flask入门 有一篇很全面的博客可以参考:Python Flask Web 框架入门 跨域问题处理 文件发送 ​

    2024年02月07日
    浏览(64)
  • Python Flask 后端向前端推送信息——轮询、SSE、WebSocket

    后端向前端推送信息,通知任务完成 轮询 SSE WebSocket 请求方式 HTTP HTTP TCP长连接 触发方式 轮询 事件 事件 优点 实现简单易兼容 实现简单开发成本低 全双工通信,开销小,安全,可扩展 缺点 消耗较大 不兼容IE 传输数据需二次解析,开发成本大 适用场景 服务端向客户端单向

    2023年04月19日
    浏览(82)
  • 【python】flask模板渲染引擎Jinja2,通过后端数据渲染前端页面

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开

    2024年04月11日
    浏览(53)
  • 大白话说Python+Flask入门(六)Flask SQLAlchemy操作mysql数据库

    这篇文章被搁置真的太久了,不知不觉拖到了周三了,当然,也算跟falsk系列说再见的时候,真没什么好神秘的,就是个数据库操作,就大家都知道的 CRUD 吧。 1、Flask SQLAlchemy简介 Flask SQLAlchemy 是基于 Flask web 框架和 SQLAlchemy ORM (对象关系映射)的工具。它旨在为 Flask web 应用

    2024年02月05日
    浏览(65)
  • Python-flask项目入门

    一、flask对于简单搭建一个基于python语言-的web项目非常简单 二、项目目录 示例代码 git路径  三、代码介绍 1、安装pip依赖 2.配置数据源 config.py 3、引用orm框架 访问数据库 /mapper/exts.py 4、启动文件 app.py 5、数据库操作 通过Flask提供orm框架对数据库进行操作 5.1增加 5.2删除 5.3修

    2024年02月14日
    浏览(35)
  • 大白话说Python+Flask入门(二)

    笔者技术真的很一般,也许只靠着 笨鸟先飞的这种傻瓜坚持 ,才能在互联网行业侥幸的 生存下来 吧! 为什么这么说? 我曾不止一次在某群,看到说我写的东西一点技术含量都没有,而且很没营养,换作一年前的我,也许会怼回去, 现在的话,我只是看到了,完事忘记了。

    2024年02月05日
    浏览(52)
  • 大白话说Python+Flask入门(三)

    今天状态很不好,我发现学这部分知识的时候,会出现溜号或者注意力无法集中的情况。 我能想到的是,大概率是这部分知识,应该是超出了我现在的水平了,也就是说我存在知识断层了,整体感觉真的是一知半解。 那有同学会问了,那你能说明白吗? 我理解的肯定能呀,

    2024年02月05日
    浏览(45)
  • 大白话说Python+Flask入门(一)

    技术这东西就得用,不用就会忘,之前写博客感觉就是给自己记笔记用,还有大部分,估计睡在语雀里都落灰了,哈哈! 在Python领域,我觉得我还是算个小白吧,会写讲不明白,所以我决定想做一件事,先搞下flask这部分教程,看看能给大家说明白吗,真的感觉和 Java 有很大

    2024年02月05日
    浏览(50)
  • flutter基础入门教程(Dart语法+UI布局+页面路由+后端连接)

    1、环境安装 1基础安装步骤教程 Android Studio安装与配置 https://juejin.cn/post/6844904054569582605 安装Android Studio前,需要先选择安装Java环境,Java需要到Oracle官网上下载安装,需要注册一个Oracle账号。 https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html Windows 10 配置Java 环境变量

    2024年02月03日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包