创建蓝图
蓝图是一种组织一组相关视图和其他代码的方法。与直接向应用程序注册视图和其他代码的方法不同,蓝图方法是将它们注册到蓝图,然后在工厂函数中将蓝图注册到应用程序。 Flaskr有两个蓝图,一个用于身份验证,另一个用于博客帖子管理。每个蓝图的代码都在一个单独的模块中。博客的使用首先需要认证,因此我们首先编写认证蓝图。
import functools
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for
)
from werkzeug.security import check_password_hash, generate_password_hash
from flaskr.db import get_db
bp = Blueprint('auth', __name__, url_prefix='/auth')
此处创建了名为“auth”的蓝图。与应用程序对象一样,蓝图需要知道它们在哪里被定义为函数的第二个参数__名称__。url_前缀将添加到与蓝图相关联的所有url前面。 使用app-register_ Blueprint()导入并注册蓝图。新代码放在工厂函数的末尾,然后返回到应用程序。
注册
@bp.route('/register', methods=('GET', 'POST'))
def register():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
db = get_db()
error = None
if not username:
error = 'Username is required.'
elif not password:
error = 'Password is required.'
elif db.execute(
'SELECT id FROM user WHERE username = ?', (username,)
).fetchone() is not None:
error = 'User {} is already registered.'.format(username)
if error is None:
db.execute(
'INSERT INTO user (username, password) VALUES (?, ?)',
(username, generate_password_hash(password))
)
db.commit()
return redirect(url_for('auth.login'))
flash(error)
return render_template('auth/register.html')
- @bp。路由与URL/register和register视图功能相关联。当Flask收到对/auth/register的请求时,它将调用register视图并返回值作为响应。 如果用户提交表单,请求方法将为“POST”。在这种情况下,将验证用户的输入。
- 要求表单是一种特殊类型的dict,它映射提交表单的键和值。在表单中,用户将输入用户名和密码。
- 验证用户名和密码不为空。
- 通过查询数据库并检查是否返回查询结果,验证用户名是否已注册。数据库。Execute使用命令与?占位符的SQL查询语句。占位符可以替换元组参数中的相应值。使用占位符的优点是,它们将自动帮助您转义输入值,以防止SQL注入。
- Fetchone()根据查询返回记录行。如果查询没有结果,则返回None。我们还使用fetchall(),它返回所有结果的列表。
- 如果验证成功,新用户数据将插入数据库。出于安全原因,密码不能以明文形式存储在数据库中。相反,使用generate_password_Hash()生成一个安全的哈希值并将其存储在数据库中。查询修改数据库中的数据后,请使用方法:dbcommit()<sqlite3.Connection。提交>保存更改。
- 保存用户数据后,它将转到登录页面。url_For()根据登录视图的名称生成相应的url。与编写固定URL相比,这样做的优点是,如果将来需要修改视图的相应URL,则无需修改与URL相关的所有代码。Redirect()为生成的URL生成重定向响应。
- 如果验证失败,将向用户显示一条错误消息。Flash()用于存储可在渲染模块中调用的信息。
- 当用户第一次访问auth/register,或者出现注册错误时,应用程序将显示一个注册表单。render_Template()将呈现一个包含HTML的模板。在本教程的下一节中,您将学习如何编写此模板。
订阅信号
可以使用connect()方法订阅信号。此方法的第一个参数是发出信号时调用的函数。第二个参数是可选的,用于定义发送方。可以使用disconnect()方法取消订阅信号。 所有核心烧瓶信号的发送方是应用程序本身。因此,当订阅信号时,请指定发送者,除非您真的想监听应用程序的所有信号。在开发扩展时,这一点尤其重要。 以下是情景管理器的一个辅助工具,可用于识别在单元测试中呈现的模板以及传递给模板的变量:
from flask import template_rendered
from contextlib import contextmanager
@contextmanager
def captured_templates(app):
recorded = []
def record(sender, template, context, **extra):
recorded.append((template, context))
template_rendered.connect(record, app)
try:
yield recorded
finally:
template_rendered.disconnect(record, app)
上面的示例可以在测试客户端中轻松使用:
with captured_templates(app) as templates:
rv = app.test_client().get('/')
assert rv.status_code == 200
assert len(templates) == 1
template, context = templates[0]
assert template.name == 'index.html'
assert len(context['items']) == 10
通过 dotenv 设置环境变量
与其在每次打开新终端For APP时都设置FLASK,不如使用FLASK的dotenv支持功能自动设置环境变量。 如果安装了python dotenv,运行烧瓶将根据中的配置设置环境变量。环境和。flaskenv公司。这可以避免在打开终端APP后手动设置FLASK,并使用环境变量配置其他类似服务。
python dotenv
命令行上设置的变量将重载中的变量。env和中的变量。flaskenv应该用于公共变量,例如FLASK_APP和。env用于私有变量,不会提交到存储库。 为了找到位置文件,将从运行烧瓶的文件夹中扫描文件夹。当前工作目录将设置为文件的位置,假设这是最高级别的项目文件夹。 这些文件只能通过“flap”命令或调用run()来加载。如果要在生产运行期间加载这些文件,应手动调用load_dotenv()
自定义命令
flap命令使用Click实现。有关如何编写命令的完整信息,请参阅项目文档。 下面的示例添加了带有name参数的createuser命令。
import click
from flask import Flask
app = Flask(__name__)
@app.cli.command("create-user")
@click.argument("name")
def create_user(name):
但是,它以命令组的形式添加,并命名为user-create。这样做有助于组织一组相关命令。
import click
from flask import Flask
from flask.cli import AppGroup
app = Flask(__name__)
user_cli = AppGroup('user')
@user_cli.command('create')
@click.argument('name')
def create_user(name):
...
app.cli.add_command(user_cli)
文件上传
用Flask上传文件很容易。只需确保不要忘记在HTML表单中设置enctype=“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_Filename()函数提供的安全:
from flask import request
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/' + secure_filename(f.filename))
标签:Flask,app,蓝图,request,user,template,dotenv,import,实现需求
From: https://blog.51cto.com/u_15568258/5780587