赞
踩
PyCharm 中新建项目
创建完成后会出现这么个项目
以下是代码解析:
- # 导入了 Flask 类
- from flask import Flask
-
- # 创建了一个 Flask web 应用的实例,并将其赋值给变量 app
- # __name__ 是一个特殊的 Python 变量,它表示当前模块的名字。在大多数情况下,如果你直接运行这个脚本,__name__ 的值会是 '__main__'
- # 传递 __name__ 给 Flask 的构造函数有助于 Flask 找到在哪里查找模板、静态文件等
- app = Flask(__name__)
-
-
- # 这是一个装饰器,它告诉 Flask 当用户访问应用的根 URL(例如 http://localhost:5000/)时,应该调用哪个函数来处理这个请求
- @app.route('/')
- # 定义函数,当 Flask 收到一个与 @app.route('/') 装饰器关联的 URL 请求时,它会调用这个函数
- def hello_world():
- return 'Hello World!'
-
-
- if __name__ == '__main__':
- # 如果脚本是作为主程序运行(即 __name__ 的值是 '__main__'),那么这行代码会启动 Flask 的开发服务器,并监听默认的端口(通常是 5000)
- app.run()
运行脚本:
为什么要开启调试模式
1. 如果开启了DEBUG模式,那么在代码中如果抛出了异常,在浏览器的页面中可以看到具体的错误信息,以及具体的错误代码位置。方便开发者调试。
2. 如果开启了DEBUG模式,那么以后在`Python'代码中修改了任何代码,只要按`ctrl+s``flask`就会自动的重新记载整个网站。不需要手动点击重新运行。
PyCharm 中开启 Debug 模式:
开启这个选项后,所处同一局域网内的主机都能访问本机的项目
如图
使用 route() 装饰器来把函数绑定到 URL:
- from flask import Flask
-
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- return '关注博主'
-
-
- @app.route('/hello')
- def hello_world():
- return 'Hello World'
-
-
- if __name__ == '__main__':
- app.run()
通过把 URL 的一部分标记为 <variable_name>
就可以在 URL 中添加变量。 标记的部分会作为关键字参数传递给函数
通过使用 <converter:variable_name>
,可以选择性的加上一个转换器,为变量指定规则
- from flask import Flask
-
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- return '关注博主'
-
-
- # string(默认值)接受任何不包含斜杠的文本
- @app.route('/hello')
- def hello_world():
- return 'Hello World'
-
-
- # int 接受正整数
- @app.route('/post/<int:post_id>')
- def show_post(post_id):
- return f'Post {post_id}'
-
-
- # float 接受正浮点数
- @app.route('/get/<float:get_id>')
- def show_get(get_id):
- return f'Get {get_id}'
-
-
- # path 类似 string ,但可以包含斜杠
- @app.route('/path/<path:subpath>')
- def show_subpath(subpath):
- return f'Subpath {subpath}'
-
-
- # uuid 接受 UUID 字符串
-
-
- if __name__ == '__main__':
- app.run()
url_for函数用于生成URL。它可以接受一个视图函数的名称作为参数,并返回与该视图函数关联的URL
- from flask import Flask, url_for
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- return 'Hello, Flask!'
-
-
- @app.route('/user/<username>')
- def user_profile(username):
- return f'Profile page of {username}'
-
-
- @app.route('/post/<int:post_id>')
- def show_post(post_id):
- return f'Post {post_id}'
-
-
- @app.route('/login')
- def login():
- return 'Login page'
-
-
- # 创建一个测试请求上下文
- # 测试请求上下文是为了模拟应用程序处理请求时的上下文环境。它允许我们在没有实际请求的情况下测试和调试路由函数的逻辑
- with app.test_request_context():
- print(url_for('index')) # 输出:/
- print(url_for('user_profile', username='john')) # 输出:/user/john
- print(url_for('show_post', post_id=1)) # 输出:/post/1
- print(url_for('login')) # 输出:/login
在上面的例子中,我们定义了几个路由函数,每个函数都有一个唯一的名称。通过url_for函数,我们可以根据这些函数的名称生成对应的URL
默认情况下,一个路由只回应 GET
请求。可以使用 route() 装饰器的 methods
参数来处理不同的 HTTP 方法
- from flask import Flask
- from flask import request
-
- app = Flask(__name__)
-
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- if request.method == 'POST':
- # 处理POST请求的逻辑
- return 'Login success!'
- else:
- # 处理GET请求的逻辑
- return 'Please login'
-
- if __name__ == '__main__':
- app.run()
上例中把路由的所有方法都放在同一个函数中,当每个方法都使用一些共同的数据时,这样是有用的
Flask 也能做好这项工作。只要在您的包或模块旁边创建一个名为 static
的文件夹就行了。静态文件位于应用的 /static
中
- from flask import Flask, url_for
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- html_url = url_for('static', filename='index.html')
- return f'<a href="{html_url}">点击链接跳转</a>'
-
-
- if __name__ == '__main__':
- app.run()
使用 render_template() 方法可以渲染模板,您只要提供模板名称和需要作为参数传递给模板的变量就行了
注意:Flask 会在 templates
文件夹内寻找模板
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>{{ name }}</h1>
- <h2>{{ age }}</h2>
- <h3>{{ sex }}</h3>
- </body>
- </html>
- from flask import Flask
- from flask import render_template
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- return render_template('index.html', name='Morant', age=19, sex='男')
-
-
- if __name__ == '__main__':
- app.run()
首先,确保已经安装了Flask-WTF
扩展包,它用于处理表单数据。可以使用pip install Flask-WTF
进行安装
通过使用 method 属性可以操作当前请求方法,通过使用 form 属性处理表单数据(在 POST
或者 PUT
请求中传输的数据)
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <title>Flask Form</title>
- </head>
- <body>
- <h1>Flask Form Example</h1>
- <form method="POST" action="/">
- {{ form.csrf_token }}
- {# 一行代码用于渲染表单对象的name字段及其对应的标签。form.name.label表示name字段的标签,form.name表示name字段的输入框。
- 通过这个语法,模板引擎会将标签和输入框的HTML代码渲染到页面中,并在它们之间添加冒号进行分隔 #}
- {{ form.name.label }}: {{ form.name }}
- {{ form.submit }}
- </form>
- </body>
- </html>
- from flask import Flask, render_template, request
- from flask_wtf import FlaskForm
- from wtforms import StringField, SubmitField
-
- app = Flask(__name__)
-
- # 设置了一个秘密密钥(SECRET_KEY)。秘密密钥是用于保护表单数据的重要配置
- app.config['SECRET_KEY'] = 'secret_key'
-
-
- # 继承自 FlaskForm 类
- # FlaskForm类是wtforms库中Form类的子类,它扩展了Form类的功能,使其与Flask框架更好地集成
- class MyForm(FlaskForm):
- # 创建一个名为Name的文本输入字段
- # 如果在HTML模板中使用{{ form.name.label }}来渲染该字段的标签,那么在浏览器中将显示一个带有文本Name的标签
- name = StringField('Name')
-
- # 创建一个标签为Submit的提交按钮字段
- # 在HTML模板中,可以使用{{ form.submit }}来渲染该字段,该字段将在浏览器中显示为一个提交按钮,文本为Submit
- submit = SubmitField('Submit')
-
-
- @app.route('/', methods=['GET', 'POST'])
- def index():
- form = MyForm()
-
- # validate_on_submit方法的作用是在表单提交的情况下进行验证
- if form.validate_on_submit():
- name = form.name.data
- return f'Hello, {name}!'
-
- # 这行代码将表单对象传递给模板,将模板渲染为最终的HTML响应,并将其返回给客户端
- return render_template('index.html', form=form)
-
-
- if __name__ == '__main__':
- app.run()
用 Flask 处理文件上传很容易,只要确保不要忘记在您的 HTML 表单中设置 enctype="multipart/form-data"
属性就可以了
补充知识点:
request.files
是Flask框架中的一个特殊字典,用于存储通过表单上传的文件。它允许您在处理HTTP请求时访问上传的文件当使用
enctype="multipart/form-data"
属性将表单的编码类型设置为多部分表单时,Flask将自动解析请求中的文件数据,并将它们存储在request.files
字典中
request.files
是一个可迭代的字典,其中键是表单中文件输入字段的名称,值是对应的文件对象。您可以通过键访问特定的文件对象,例如request.files['file']
将返回名为file
的文件对象每个文件对象都有一些有用的属性,例如
filename
表示上传文件的原始文件名,stream
表示文件的字节流,content_type
表示文件的MIME类型等
- <!DOCTYPE html>
- <html>
- <head>
- <title>File Upload</title>
- </head>
- <body>
- <h1>File Upload</h1>
- <form action="/upload" method="POST" enctype="multipart/form-data">
- <input type="file" name="file">
- <input type="submit" value="Upload">
- </form>
- </body>
- </html>
- from flask import Flask, render_template, request
- from werkzeug.utils import secure_filename
- import os
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- # 渲染模板
- return render_template('index.html')
-
-
- @app.route('/upload', methods=['POST'])
- def upload_file():
- # 检查请求中是否存在名为file的文件。它通过查看request.files字典来检查文件是否存在
- if 'file' not in request.files:
- return 'No file uploaded', 400
-
- file = request.files['file']
-
- if file.filename == '':
- return 'No file selected', 400
-
- if file:
- # secure_filename()函数是Flask框架中的一个实用函数,用于将文件名转换为安全的文件名格式
- filename = secure_filename(filename)
- # 使用file.save()方法将文件保存到服务器上的指定目录中
- file.save(os.path.join('uploads', filename))
- return 'File uploaded successfully'
-
- return 'File upload failed', 500
-
-
- if __name__ == '__main__':
- app.run()
要访问 cookies ,可以使用 cookies 属性。可以使 用响应对象的 set_cookie 方法来设置 cookies
- from flask import Flask, request, make_response
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- # make_response('Cookie has been set!')是Flask框架中用于创建响应对象的函数
- # 它接受一个参数作为响应的内容,并返回一个包含该内容的响应对象
- # make_response('Cookie has been set!')创建了一个响应对象,响应的内容是字符串'Cookie has been set!'
- # 这个响应对象将被返回给客户端,作为对请求的响应
- resp = make_response('Cookie has been set!')
- # 设置 Cookie
- # 它接受两个参数,第一个参数是cookie的名称,第二个参数是cookie的值
- resp.set_cookie('username', 'Morant')
- return resp
-
-
- @app.route('/get_cookie')
- def get_cookie():
- # 从请求中获取cookie
- username = request.cookies.get('username')
- return f'Username: {username}'
-
-
- if __name__ == '__main__':
- app.run()
使用redirect()函数可以重定向。使用 abort() 可以更早退出请求,并返回错误代码
使用 erroehander() 装饰器可以定制出错页面
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <title>File Upload</title>
- </head>
- <body>
- <h1>重定向和自定义错误</h1>
- </body>
- </html>
- from flask import Flask, redirect, url_for, abort, render_template
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- # 重定向到另一个路由
- return redirect(url_for('hello'))
-
-
- @app.route('/hello')
- def hello():
- try:
- # 当num为0时,中止请求并返回状态码为400的错误响应
- num = 0
- result = 10 / num
- return f'10 divided by {num} is {result}'
- except ZeroDivisionError:
- # 捕获ZeroDivisionError异常并返回自定义的错误页面
- # 在这个例子中,return abort(400)会中止当前请求,并返回状态码为400的错误响应
- return abort(400)
-
-
- # errorhandler(400)是Flask框架中用于处理指定状态码错误的装饰器
- # 在这个例子中,@app.errorhandler(400)装饰器将下面的bad_request函数注册为处理状态码为400的错误的函数
- @app.errorhandler(400)
- # # 在这个例子中,bad_request函数会渲染一个名为index.html的模板,并返回该模板的响应。同时,使用状态码400来表示该响应
- def bad_request(error):
- # 自定义400错误页面
- return render_template('index.html'), 400
-
-
- if __name__ == '__main__':
- app.run()
在Flask中,当视图函数返回一个值时,它会自动转换为一个响应对象,用于向客户端返回数据。根据返回值的不同类型,会有不同的转换规则:
1. 如果返回值是一个响应对象,那么它会直接被返回。
2. 如果返回值是一个字符串,那么它会被转换为一个带有默认参数的响应对象,包含该字符串作为响应主体,状态码为 200 OK,并且内容类型为text/html。
3. 如果返回值是一个迭代器或生成器,那么它会被视为一个流式响应,将字符串或字节逐步返回给客户端。
4. 如果返回值是一个字典或列表,Flask会调用`jsonify()`函数来创建一个响应对象,将字典或列表转换为JSON格式。
5. 如果返回值是一个元组,那么元组中的项目可以提供额外的信息。元组必须至少包含一个项目,可以是`(response, status)`、`(response, headers)`或`(response, status, headers)`形式。其中,status的值会覆盖默认的状态码,headers是一个包含额外头部值的列表或字典。
6. 如果以上规则都不适用,Flask会假设返回值是一个有效的WSGI应用程序,并将其转换为一个响应对象。
如果想在视图函数内部对响应对象进行更精细的控制,可以使用`make_response()`函数来创建响应对象,并对其进行设置。
在这个例子中,视图函数response
使用make_response()
函数创建了一个自定义的响应对象resp
。然后,它将该响应对象直接返回给客户端,Flask会将其发送给客户端作为响应
- from flask import Flask, make_response
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def response():
- # 创建自定义响应对象
- resp = make_response('Hello, Flask!')
- resp.headers['Content-Type'] = 'text/plain'
- resp.status_code = 200
- return resp
-
-
- if __name__ == '__main__':
- app.run()
当访问根目录/时,视图函数hello返回一个字符串"Hello, Flask!"
Flask会自动将该字符串转换为一个响应对象,状态码为200 OK,内容类型为text/html,并将该字符串作为响应主体返回给客户端
- from flask import Flask
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def hello():
- return "Hello, Flask!"
-
-
- if __name__ == '__main__':
- app.run()
在这个例子中,视图函数stream
返回一个迭代器/生成器generate
。这个生成器通过使用yield
关键字逐步生成响应的字符串内容。Flask会将每个生成的字符串立即发送给客户端,使得响应成为一个流式响应
- from flask import Flask
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def stream():
- def generate():
- yield 'Hello,'
- yield 'Flask!'
-
- return generate()
-
-
- if __name__ == '__main__':
- app.run()
注意,生成器函数在第一次迭代时从函数体的开始处执行,然后在遇到第一个 yield
时暂停。在后续的迭代中,它从上一次暂停的 yield
语句之后继续执行,直到遇到下一个 yield
,或者函数结束
当访问根目录/
时,视图函数data
返回一个字典{'name': 'John', 'age': 25}
。Flask会自动调用jsonify()
函数将字典转换为JSON格式,并创建一个响应对象来返回给客户端
- from flask import Flask, jsonify
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def data():
- return {'name': 'John', 'age': 25}
-
-
- if __name__ == '__main__':
- app.run()
当访问根目录/
时,视图函数response
返回一个元组('Hello, Flask!', 201)
。元组中的第一个项目是响应主体,第二个项目是状态码。Flask会根据这个元组创建一个响应对象,并将其返回给客户端
- from flask import Flask
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def response():
- return 'Hello, Flask!', 201
-
-
- if __name__ == '__main__':
- app.run()
当访问根目录/
时,视图函数response
使用make_response()
函数创建一个响应对象,并对其进行设置。在这个例子中,我们手动设置了响应主体、内容类型和状态码,并将该响应对象返回给客户端
- from flask import Flask, make_response
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def response():
- resp = make_response('Hello, Flask!')
- resp.headers['Content-Type'] = 'text/plain'
- resp.status_code = 200
- return resp
-
-
- if __name__ == '__main__':
- app.run()
当视图函数返回一个字典或列表时,可以使用jsonify()
函数将其转换为JSON格式,并创建一个响应对象返回给客户端。下面是一个使用jsonify()
函数的案例:
- from flask import Flask, jsonify
-
- app = Flask(__name__)
-
-
- @app.route('/')
- def data():
- data = {'name': 'John', 'age': 25}
- return jsonify(data)
-
-
- if __name__ == '__main__':
- app.run()
使用会话之前您必须设置一个密钥
- from flask import Flask, session, redirect, url_for
-
- app = Flask(__name__)
- app.secret_key = 'your_secret_key'
-
-
- @app.route('/')
- def index():
- session['username'] = 'Morant'
- return 'Session is set!'
-
-
- @app.route('/profile')
- def profile():
- if 'username' in session:
- return f"Welcome, {session['username']}!"
- else:
- return redirect(url_for('index'))
-
-
- @app.route('/logout')
- def logout():
- session.pop('username', None)
- return 'Logged out!'
-
-
- if __name__ == '__main__':
- app.run()
在这个例子中,我们首先设置了一个密钥secret_key
,用于加密会话数据。然后,当访问根目录/
时,视图函数index
将用户名John
存储在会话中的username
键中。
接下来,当访问/profile
时,视图函数profile
将检查会话中是否存在username
键。如果存在,它会欢迎用户,并显示用户名。否则,它会重定向到index
视图函数来设置会话。
最后,当访问/logout
时,视图函数logout
会从会话中删除username
键,以模拟用户注销操作。
通过使用会话,我们可以在不同的请求之间存储和访问数据,以实现用户认证、保持登录状态等功能。
flash()
函数用于在视图函数中闪现一条消息,这条消息可以在后续的请求中被读取和显示
而get_flashed_messages()
函数用于在模板中获取并操作这些消息
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <title>File Upload</title>
- </head>
- <body>
- <h1>Profile</h1>
- {% for message in messages %}
- <p>{{ message }}</p>
- {% endfor %}
- </body>
- </html>
- from flask import Flask, flash, redirect, render_template, url_for, get_flashed_messages
-
- app = Flask(__name__)
- app.secret_key = 'your_secret_key'
-
-
- @app.route('/')
- def index():
- flash('This is a flashed message!')
- return redirect(url_for('profile'))
-
-
- @app.route('/profile')
- def profile():
- messages = get_flashed_messages()
- return render_template('index.html', messages=messages)
-
-
- if __name__ == '__main__':
- app.run()
在这个例子中,当访问根目录/
时,视图函数index
使用flash()
函数来闪现一条消息,然后它会重定向到profile
视图函数
在profile
视图函数中,使用get_flashed_messages()
函数来获取闪现的消息,然后将这些消息传递给模板profile.html
进行显示
在模板profile.html
中,可以使用Jinja2的模板语法来遍历并显示消息
在这个例子中,我们定义了一个根路由/
,当访问该路由时,会记录不同级别的日志信息。
通过app.logger.debug()
、app.logger.info()
、app.logger.warning()
和app.logger.error()
函数,我们可以分别记录调试、信息、警告和错误级别的日志信息
- from flask import Flask
-
- app = Flask(__name__)
-
- @app.route('/')
- def index():
- app.logger.debug('This is a debug message')
- app.logger.info('This is an info message')
- app.logger.warning('This is a warning message')
- app.logger.error('This is an error message')
- return 'Logged messages'
-
- if __name__ == '__main__':
- app.run()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。