Flask企业级应用开发:蓝图与SQLAlchemy最佳实践
引言
Flask是一个轻量级的Python网络框架,具备用于在Python中创建网络应用程序的有用工具和功能。SQLAlchemy是一个SQL工具包,为关系型数据库提供高效且高性能的访问。它提供了与多个数据库引擎(如SQLite、MySQL和PostgreSQL)交互的方法,通过提供对数据库的SQL功能的访问。该工具包还提供了一个对象关系映射器(ORM),使您能够使用简单的Python对象和方法进行查询和处理数据。Flask-SQLAlchemy是Flask的扩展,使得在Flask应用程序中使用SQLAlchemy更加容易,提供了与数据库交互的工具和方法。
Flask提供了一种快速构建小型Web应用程序的方式,只需一个Python文件。然而,一个小应用程序可能会逐渐发展成具有多个数据库表、数百个路由和复杂功能的大型应用程序。在一个文件中编写大型应用程序的代码将很快变得杂乱且难以管理。Flask允许您通过将应用程序的主要部分拆分到特定的目录和文件中来组织应用程序的代码库,以获得一个更有组织的应用程序。
举个例子,在一个社交媒体应用中,你可能会在一个名为routes.py的文件中保存用户的路由,该文件位于一个名为users的目录内。然后,你可以在一个名为users.py的模块中收集用户的数据库模型,该模块位于一个名为models的目录内。接下来,你可以以相同的方式为帖子、关注者、标签、问题、答案、广告、市场和支付等功能做相应的设置在你功能复杂的社交媒体应用中。如果你想要将一些业务逻辑编辑到支付代码中,你可以在mysocialapp/models/payment.py文件中更改支付的数据库代码,然后在mysocialapp/payments/routes.py文件中更改相应的业务逻辑。每个应用的部分都会在不同的文件和目录中独立进行代码隔离,这有效地将应用程序拆分成易于管理的组件。这种结构还有助于让新开发人员熟悉你的应用,以便他们知道在哪里解决问题或添加新功能。
Flask 提供了一种称为蓝图的功能,用于创建应用程序组件。在之前的例子中,你可以使用蓝图来构建一个大型社交媒体应用程序,每个功能都有不同的蓝图,比如用户的蓝图、帖子的蓝图、关注者的蓝图等等,以此结构化你的应用程序。
在本教程中,您将使用Flask蓝图为一个具备三个组件的web应用程序进行结构化,主要蓝图包含首页和其他主要路由,文章蓝图负责管理博客文章,问题蓝图负责处理问题和答案。
先决条件
- 一个本地Python 3编程环境,您可以按照《如何安装和设置Python 3本地编程环境》系列教程中针对您发行版的说明进行设置。在本教程中,我们将我们的项目目录称为flask_app。
- 对基本Flask概念的理解,如路由、视图函数和模板。如果您不熟悉Flask,请查看《如何使用Flask和Python创建您的第一个Web应用程序》和《如何在Flask应用程序中使用模板》。
- 对基本HTML概念的理解。您可以查看我们的《如何使用HTML构建网站》教程系列以获取背景知识。
- 对基本Flask-SQLAlchemy概念的理解,如设置数据库、创建数据库模型和将数据插入数据库。请参阅《如何在Flask应用程序中使用Flask-SQLAlchemy与数据库交互》以获取背景知识。
目标应用结构
在教程结束时,您将完成一个拥有以下结构的Flask应用程序。
.
└── flask_app
├── app
│ ├── extensions.py
│ ├── __init__.py
│ ├── main
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── models
│ │ ├── post.py
│ │ └── question.py
│ ├── posts
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── questions
│ │ ├── __init__.py
│ │ └── routes.py
│ └── templates
│ ├── base.html
│ ├── index.html
│ ├── posts
│ │ ├── categories.html
│ │ └── index.html
│ └── questions
│ └── index.html
├── app.db
└── config.py
在您的flask_app目录中,您将有一个名为app.db的数据库文件和一个名为config.py的Flask应用程序的配置文件。主要的Flask应用程序将位于app目录中,该目录将有一个名为__init__.py的特殊文件,使其成为一个用于正常工作的导入的包,它将包含一个用于创建Flask应用程序实例的函数。
应用目录中将包含一个extensions.py文件来管理您在应用程序中使用的Flask扩展(在本教程中,使用Flask-SQLAlchemy作为使用Flask扩展的示例)。您还将拥有以下目录:
- main: 主要蓝图,用于主页等主要路由。
- posts: 文章蓝图,用于管理博客文章。
- questions: 问题蓝图,用于处理问题和答案。
- models: 将包含Flask-SQLAlchemy模型的目录。
- templates: 模板目录,将包含主要蓝图的文件以及每个蓝图的目录。
第一步 – 安装Flask和Flask-SQLAlchemy
在这一步中,您将安装所需的应用程序包。
在你的flask_app目录中,激活你的虚拟环境。
source my_env /bin/activate
在您的虚拟环境中激活后,使用pip安装Flask和Flask-SQLAlchemy。
pip install Flask Flask-SQLAlchemy
一旦安装完成,输出将打印类似以下内容的行:
输出
Successfully installed Flask-2.1.2 Flask-SQLAlchemy-2.5.1 Jinja2-3.1.2 MarkupSafe-2.1.1 SQLAlchemy-1.4.39 Werkzeug-2.1.2 click-8.1.3 greenlet-1.1.2 itsdangerous-2.1.2
在安装了所需的Python包之后,您将在下一步中设置一个配置文件来管理您的Flask应用程序的设置。
步骤2 — 创建配置文件
在这一步中,您将为您的Flask应用程序创建一个配置文件,将应用程序设置与应用程序的其余部分分离,使更改设置更加容易。配置文件将配置诸如密钥、SQLAlchemy数据库URI等内容。
在你的flask_app目录中,打开一个名为config.py的新文件。这个文件将保存你的Flask应用程序的配置。
nano config.py
将以下代码添加到其中:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY')
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI')\
or 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
保存并关闭文件。
你需要导入os模块来访问你的文件系统。你使用os模块来通过os.path.abspath(os.path.dirname(__file__))来建立基础目录,以正确设定数据库文件的路径。
你使用一个名为Config的类,并使用类变量设置配置值。在这里,你需要设置三个配置项。
- SECRET_KEY:Flask用作密钥的长随机字符串,用于保护会话(session)中从一个请求到另一个请求之间保存的信息。用户可以访问存储在会话中的信息,但除非他们拥有密钥,否则无法修改它,因此你绝不能让任何人访问你的密钥。有关更多信息,请参阅Flask文档中关于会话的部分。其他Flask扩展通常也使用这个密钥来保护数据。有关如何创建安全密钥的更多信息,请参阅《如何在Flask应用程序中使用Web表单》的步骤3。在开发Flask应用程序时,你应该使用名为SECRET_KEY的环境变量来设置密钥。要在这个config.py文件中获取其值并将其保存在名为SECRET_KEY的类变量中,你可以通过os.environ对象的get()方法访问环境变量的值。(虽然按照本教程你不需要设置密钥,但你可以查看本列表末尾的注释,了解如何设置密钥的说明。)
- SQLALCHEMY_DATABASE_URI:数据库URI指定了你想使用SQLAlchemy建立连接的数据库。在这种情况下,你可以从DATABASE_URI环境变量获取它,或者设置一个默认值。这里的默认URI值遵循sqlite:///path/to/app.db的格式。你使用os.path.join()函数将你构建并存储在basedir变量中的基础目录和app.db文件名连接起来。有了这个,创建Flask应用程序而不设置DATABASE_URI环境变量将默认连接到flask_app目录中的app.db数据库文件。该文件将在你创建数据库表时创建。如果你想为不同的SQL引擎设置数据库URI,请参阅《如何在Flask应用程序中使用Flask-SQLAlchemy与数据库交互》的步骤2。
- SQLALCHEMY_TRACK_MODIFICATIONS:用于启用或禁用对象修改跟踪的配置。你将其设置为False以禁用跟踪并减少内存使用。更多信息,你可以阅读Flask-SQLAlchemy文档中的配置页面。
注意:在本教程中,您不需要设置一个秘密密钥,因为您不会使用需要秘密密钥的功能。但是,如果您需要设置一个秘密密钥,您可以按以下方式设置它(在Windows上使用set而不是export):
set SECRET_KEY="your secret key"
同样,您可以按以下方式设置数据库URI(在Windows上使用set):
set DATABASE_URI="postgresql://username:password@host:port/database_name"
你现在已经为你的应用程序设置了一个配置文件。接下来,你将设置一个Flask应用程序实例,并创建一些代表Flask应用程序不同组件的蓝图。
步骤 3 — 创建一个 Flask 应用工厂
在这个步骤中,您将创建一个Flask应用工厂,这是一个设置Flask应用实例的Python函数。
在教程的这个阶段,你的flask_app目录结构如下(不包括虚拟环境的目录):
.
├── flask_app
└── config.py
你的应用程序的核心代码将存在于一个项目目录中,该目录将是一个Python包。在本教程中,我们将它称为app,但你可以使用你的项目名称或其他常用目录名称,比如src、core或类似的名称。
你需要将包含应用程序核心代码的文件夹变成一个Python包,以便在整个代码库中正确地进行导入,从而提高其可维护性。
为了将应用程序项目目录变成Python包,您需要在其中创建一个特殊的__init__.py文件,将目录标记为Python包。这个__init__.py文件将包含用于Flask工厂函数的代码,该函数是一个您用来设置和创建Flask应用程序实例的函数,在该函数中您将连接所有的Flask蓝图。将工厂函数视为一个中心函数,您可以在其中将所有的Flask组件(蓝图)组合成一个应用程序,并可以用它来创建不同目的和不同配置的不同Flask应用程序实例。例如,您可以使用工厂函数创建一个用于测试的Flask应用程序实例,并为测试配置合适的配置。
在你的 flask_app 目录中,创建一个名为 app 的新目录。
mkdir app
然后在app目录下打开一个新的__init__.py文件。
nano app/__init__.py
将以下代码添加到其中。
from flask import Flask
from config import Config
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Initialize Flask extensions here
# Register blueprints here
@app.route('/test/')
def test_page():
return '<h1>Testing the Flask Application Factory Pattern</h1>'
return app
保存并关闭文件。
在这个文件中,你从flask包中导入了Flask类。然后你从前一步骤中在flask_app目录中创建的config.py文件中导入了Config配置类。
create_app()函数是Flask应用工厂函数。它使用Flask()类中的app = Flask (__name__)一行来创建一个名为app的应用实例。通过从一个对象中使用app.config.from_object()方法导入配置值来配置应用,将config_class参数的值传递给它,config_class参数的默认值为Config类。你可以在以下的“# 在这里初始化Flask扩展”注释下初始化你的Flask扩展,并在创建蓝图后在“# 在这里注册蓝图”注释下注册你的应用蓝图。
你可以使用app.route()装饰器在工厂函数内创建一个测试路由,来演示如何在应用工厂中注册路由。在这种情况下,test_page()视图函数返回的标题为“测试Flask应用工厂模式”。
最后,create_app() 工厂函数返回你使用 return app 构建的应用程序实例。
Flask会自动检测您的app包中的create_app()工厂函数,并使用它来创建应用程序实例。但是,在开始以开发模式运行Flask应用程序之前,您需要先设置所需的环境变量。
当在你的 flask_app 目录中并且已经激活了你的虚拟环境,你将通过将核心应用的目录名称 app 作为值传递给 FLASK_APP 环境变量来告诉 Flask 工厂函数的位置。然后,你将把 FLASK_ENV 环境变量设置为 development 以在开发模式下运行应用程序并获得调试器的访问权限。有关 Flask 调试器的更多信息,请参阅:如何处理 Flask 应用程序中的错误。
首先,将应用程序包设置为Flask应该查找create_app()工厂函数的位置。
export FLASK_APP = app
你可能习惯于在一个名为 app.py 的单一 Python 文件中构建你的 Flask 应用程序。在这种情况下,你也使用相同的命令告诉 Flask 应用程序所在的位置。不同之处在于上述命令中的 app 是项目的核心目录,在那里你有你的 __init__.py 文件。
将FLASK_ENV环境变量设为开发模式来运行应用程序。
export FLASK_ENV = development
然后运行该应用程序。
flask run
在开发服务器运行的情况下,使用浏览器访问以下URL。
http://127.0.0.1:5000/test/
该网站将会加载一个标题为“测试Flask应用程序工厂模式”的页面。
现在你已经创建了一个Flask应用程序工厂函数。接下来,你将在这个工厂函数中创建Flask蓝图并注册它们。
第四步 — 创建Flask蓝图在这一步中,您将为管理Flask应用程序的主要组件创建主要路由的蓝图,然后在工厂函数上注册该蓝图。您将为博客文章、问题和答案分别创建另一个蓝图。您将为每个蓝图添加几个路由,并为每个路由使用模板目录渲染模板。
在教程的这一点上,您的flask_app目录结构如下(不包括虚拟环境的目录):
.
├── flask_app
├── app
│ └── __init__.py
└── config.py
创建主要蓝图并渲染其模板。你现在将为应用程序创建主要的蓝图,并呈现它的模板。
保持您在前一步中启动的开发服务器运行,并打开一个新的终端。
在新终端中导航到您的 flask_app 目录。然后在 app 目录中创建一个名为 main 的目录,用作您的主要蓝图。
mkdir app/main
接下来,在新的主文件夹中打开一个新的__init__.py主文件。
nano app/main/__init__.py
这是你创建主要蓝图的地方。将以下代码添加到此文件中。
from flask import Blueprint
bp = Blueprint('main', __name__)
保存并关闭文件。
在这里,你从flask包中导入了Blueprint类。然后,你使用这个类来创建了一个蓝图对象bp,向它传入了两个参数:一个名字(在这个例子中为’main’)和__name__特殊变量,该变量保存了当前Python模块的名字。
你现在有一个蓝图对象,稍后将有路由和函数可以插入到你使用之前编写的create_app()工厂函数创建的Flask应用程序中。
接下来你将在主要的蓝图目录中创建一个routes.py文件,该文件将保存主要蓝图的路由。在主要蓝图目录中打开一个新的routes.py文件。
nano app/main/routes.py
您将使用bp对象来创建路由。在新文件中添加以下路由:
from app.main import bp
@bp.route('/')
def index():
return'This is The Main Blueprint'
保存并关闭文件。
这里,你从主蓝图中导入了bp蓝图对象,通过app.main进行访问。在导入语句中,app是项目的包,main是主蓝图的包,bp是你在主蓝图的__init__.py文件中声明的对象。
你可以使用bp对象通过bp.route()装饰器来创建一个/路由和一个index()视图函数,类似于熟悉的app.route()装饰器。
要让Flask使用这些路由,并且可以直接从蓝图中导入它们,你需要在蓝图的__init__.py文件中导入routes.py文件。打开它进行编辑。
nano app/main/__init__.py
在文件末尾添加突出显示的导入行。
翻译:flask_app / app / main / __init__.py
Flask应用程序的主要初始化文件是__init__.py。
from flask import Blueprint
bp = Blueprint('main', __name__)
from app.main import routes
保存并关闭文件。
通过这个添加,注册一个蓝图也会注册它的路由。
既然你已经创建了蓝图并添加了路由,现在你需要告诉Flask这个新的蓝图,以便它被视为你的Flask应用程序的一部分。为了做到这一点,你需要在Flask应用程序工厂函数中注册蓝图。
打开app/__init__.py文件来编辑你的工厂函数。
nano app/__init__.py
修改create_app()工厂函数以匹配以下模块添加下划线标记的代码块。
...
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Initialize Flask extensions here
# Register blueprints here
from app.main import bp as main_bp
app.register_blueprint(main_bp)
@app.route('/test/')
def test_page():
return '<h1>Testing the Flask Application Factory Pattern</h1>'
return app
保存并关闭文件。
你从主蓝图中导入bp蓝图对象,并将其重命名为main_bp,以提高可读性。然后,你使用app.register_blueprint()方法来注册这个主蓝图,让Flask将其视为应用程序的一部分。
在开发服务器运行时,导航到以下 URL。
http://127.0.0.1:5000/
这个页面会加载带有“这是主要蓝图”这段文本,这是你在主路径返回的文本。
现在你的应用程序中有一个路由的蓝图。接下来,你将编辑主蓝图的主路由,以渲染一个HTML模板,这将展示在使用Flask蓝图时如何渲染模板的方法。
打开主蓝图的routes.py文件进行修改。
nano app/main/routes.py
用突出显示的行编辑文件
from flask import render_template
from app.main import bp
@bp.route('/')
def index():
return render_template('index.html')
保存并关闭文件。
在这里,你导入了render_template()函数,并在路由中使用它来渲染一个名为index.html的模板文件。
您现在需要创建一个模板目录和一个基础模板,以避免代码重复,其他所有模板都可以共享。
在您的应用目录中创建一个模板目录。
mkdir app/templates
打开一个名为base.html的新文件作为基本模板。
nano app/templates/base.html
将以下代码添加到新文件中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} {% endblock %} - FlaskApp</title>
<style>
h2 {
width: 100%;
}
.title {
margin: 5px;
width: 100%;
}
.content {
margin: 5px;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.post {
flex: 20%;
padding: 10px;
margin: 5px;
background-color: #f3f3f3;
inline-size: 100%;
}
.title a {
color: #00a36f;
text-decoration: none;
}
nav a {
color: #d64161;
font-size: 3em;
margin-left: 50px;
text-decoration: none;
}
</style>
</head>
<body>
<nav>
<a href="{{ url_for('main.index') }}">FlaskApp</a>
<a href="#">Posts</a>
<a href="#">Categories</a>
<a href="#">Questions</a>
</nav>
<hr>
<div class="content">
{% block content %} {% endblock %}
</div>
</body>
</html>
保存并关闭文件。
这个基本模板包含了HTML样板,你可以在其他模板中重复使用。
基本模板包括标题块、一些CSS样式、用于链接到应用程序不同部分的导航栏以及内容块。查看《在Flask应用程序中如何使用模板》以获取更多关于基本模板的信息。
使用语法 `blueprint_name.view_function_name` 来在使用 `url_for()` 函数与蓝图一起时链接到一个路由。首页由主要蓝图中的 `index()` 视图函数处理;因此,你需要将 `main.index` 传递给 `url_for()` 函数来构建一个链接。
现在,在主蓝图的index()视图函数中创建您渲染的index.html文件。
nano app/templates/index.html
将以下代码添加到新创建的文件中。
{% extends 'base.html' %}
{% block content %}
{% block title %} The Home Page of FlaskApp {% endblock %}
This is the main Flask blueprint
{% endblock %}
保存并关闭文件。
在这里,你扩展基础模板。你替换内容块,使用一个同时作为标题的
标签和一个
标签来表示索引页是主要的Flask蓝图的一部分。在开启开发服务器的情况下,使用您的浏览器访问首页页面,或者如果它已经打开了,请刷新它。
http://127.0.0.1:5000/
http://127.0.0.1:5000/
一个类似下面图像的页面将加载:

创建帖子蓝图并渲染其模板。现在您将要创建博客文章的蓝图,将其注册并渲染其模板。
在本处教程中,您的Flask应用目录结构如下(不包括虚拟环境的目录):
.
├── flask_app
├── app
│ ├── __init__.py
│ ├── main
│ │ ├── __init__.py
│ │ └── routes.py
│ └── templates
│ ├── base.html
│ └── index.html
└── config.py
为了为博客文章创建新的蓝图,你将按照前一节中的相同步骤进行。
首先,创建一个新的“文章目录”来存放蓝图文件。
mkdir app/posts
接下来,在新的posts目录中打开一个新的__init__.py文件。
nano app/posts/__init__.py
创建一个bp蓝图对象,并将要创建的路由导入到蓝图的routes.py文件中。
from flask import Blueprint
bp = Blueprint('posts', __name__)
from app.posts import routes
保存并关闭文件。
在上述代码块中,您使用了“posts”作为蓝图的名称。您还从一个尚未创建的routes.py文件中导入了路由。
接下来,打开新的routes.py文件,你将在这里为帖子蓝图添加路由:
nano app/posts/routes.py
请将以下路由添加到这个文件中。
from flask import render_template
from app.posts import bp
@bp.route('/')
def index():
return render_template('posts/index.html')
@bp.route('/categories/')
def categories():
return render_template('posts/categories.html')
保存并关闭文件。
在这里,你有两个路径:一个是用于应用程序帖子组件的索引页面的路径,另一个是用于类别的路径,这将成为帖子组件的一部分。
这里有两条路径可供选择:一条是用于应用程序帖子组件的索引页面的路径,另一条是类别的路径,将成为帖子组件的一部分。
在索引路由中,您使用模板文件路径为 posts/index.html 进行渲染,这意味着 Flask 将会在 templates 目录中查找名为 posts 的文件夹,然后在该文件夹内部查找 index.html 文件。
在分类路由中,你会渲染一个categories.html模板,该模板还将位于模板文件夹内的一个名为posts的目录中。
现在在你的模板目录内创建一个新的帖子目录。
mkdir app/templates/posts
接下来,在posts目录中创建一个新的index.html文件。这是你在posts蓝图的index()视图函数中呈现的文件。
nano app/templates/posts/index.html
将以下代码添加到新创建的文件中。
flask_app/app/templates/posts/index.html翻译:Flask应用程序中的模板文件夹中的posts/index.html
使用Flask蓝图构建大型应用程序(第5部分)
这是文章《如何使用Flask蓝图和Flask-SQLAlchemy构建一个大型的Flask应用程序》的第5部分(共10部分)。
首先,创建帖子页面的模板文件:
{% extends 'base.html' %}
{% block content %}
{% block title %} 帖子页面 {% endblock %}
这是Flask帖子蓝图
{% endblock %}
保存并关闭文件。
在这里,您扩展了基本模板。您还设置了一个标题,将页面标记为帖子模板的一部分。接下来,在posts目录下创建一个新的categories.html文件。这就是你在posts蓝图的categories()视图函数中渲染的文件。
nano app/templates/posts/categories.html
将以下代码添加到新创建的文件中:
{% extends 'base.html' %}
{% block content %}
{% block title %} 分类页面 {% endblock %}
这是帖子蓝图中的分类页面
{% endblock %}
保存并关闭文件。
您可以扩展基础模板,并将标题设置为将页面标记为帖子蓝图的一部分。你已经创建了帖子的蓝图,添加了路由,并创建了渲染的模板。现在,你需要在Flask的工厂函数中注册这个蓝图,让Flask将其识别为应用程序的一部分。
打开app/__init__.py文件来编辑你的工厂函数:
nano app/__init__.py
通过添加高亮显示的代码行来编辑create_app()工厂函数:
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# 在这里初始化Flask扩展
# 在这里注册蓝图
from app.main import bp as main_bp
app.register_blueprint(main_bp)
from app.posts import bp as posts_bp
app.register_blueprint(posts_bp, url_prefix='/posts')
@app.route('/test/')
def test_page():
return '<h1>测试Flask应用程序工厂模式</h1>'
return app
保存并关闭文件。
在这里,您从帖子蓝图包中导入了bp蓝图对象,并将其重命名为posts_bp,以提高可读性。
你可以使用app.register_blueprint()方法注册posts_bp蓝图对象,并传递给它名为’/posts’的url_prefix参数,该参数将为蓝图的路由添加前缀。例如,posts蓝图的主要路由将通过/posts/路径访问,而/categories路由将在/posts/categories/路径上。
在你的新的帖子蓝图注册并且开发服务器运行时,使用你的浏览器导航至以下网址:
http://127.0.0.1:5000/posts/
http://127.0.0.1:5000/posts/categories/
在http://127.0.0.1:5000/posts/页面上将显示”帖子页面”标题。在http://127.0.0.1:5000/posts/categories/页面上,将显示”分类页面”标题。
为了使导航栏中的帖子和分类链接功能正常,打开基本模板进行修改:
nano app/templates/base.html
使用下面的代码修改<nav>标签:
<nav>
<a href="{{ url_for('main.index') }}">Flask应用</a>
<a href="{{ url_for('posts.index') }}">帖子</a>
<a href="{{ url_for('posts.categories') }}">分类</a>
<a href="#">问题</a>
</nav>
保存并关闭文件。
你可以使用url_for(‘posts.index’)函数调用来链接到帖子索引页面,使用url_for(‘posts.categories’)来链接到分类页面。
刷新您应用程序中的任何页面以启用帖子和类别链接的功能。
您现在的应用程序中已经注册了一个帖子的蓝图。接下来,您将添加一个问题和答案的蓝图。
创建问题蓝图并渲染其模板
现在您将创建问题蓝图,注册它,并渲染其模板。
在教程的这一部分中,你的flask_app目录结构如下所示(不包括虚拟环境的目录):
.
├── flask_app
├── app
│ ├── __init__.py
│ ├── main
│ │ ├── __init__.py
│ │ └── routes.py
│ ├── posts
│ │ ├── __init__.py
│ │ └── routes.py
│ └── templates
│ ├── base.html
│ ├── index.html
│ └── posts
│ ├── categories.html
│ └── index.html
└── config.py
为了为问题和答案创建一个新的蓝图,创建一个新的问题目录来保存蓝图文件:
mkdir app/questions
接下来,在新的questions目录中打开一个新的__init__.py文件:
nano app/questions/__init__.py
在routes.py文件中创建一个bp蓝图对象,并导入之后要创建的路由:
from flask import Blueprint
bp = Blueprint('questions', __name__)
from app.questions import routes
保存并关闭文件。
在前面的代码块中,你使用了问题作为蓝图的名称。你还导入了路由文件中的路由,但你尚未创建该文件。
接下来,打开新的routes.py文件,在这里你将为问题蓝图设置路由:
nano app/questions/routes.py
将以下路由添加到此文件中:
from flask import render_template
from app.questions import bp
@bp.route('/')
def index():
return render_template('questions/index.html')
保存并关闭文件。
你可以使用问题蓝图对象创建一个路由,将一个名为index.html的模板文件渲染到名为questions的目录中,而这个questions目录将会在templates文件夹中创建。
在模板目录下创建一个问题目录,然后在其中打开一个index.html文件:
mkdir app/templates/questions
nano app/templates/questions/index.html
将以下代码添加到新文件中:
{% extends 'base.html' %}
{% block content %}
{% block title %} 问题页面 {% endblock %}
这是问题蓝图中的首页
{% endblock %}
{% extends 'base.html' %}
{% block content %}
{% block title %} Questions {% endblock %}
Questions Blueprint
{% endblock %}
保存并关闭文件。
在这里,你需要设置一个标题和一个副标题,类似于其他蓝图中的以前的索引模板。
现在打开app/__init__.py,在create_app()工厂函数中注册questions蓝图。
nano app/__init__.py
通过添加下面的代码行来编辑create_app()工厂函数:
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
# Initialize Flask extensions here
# Register blueprints here
from app.main import bp as main_bp
app.register_blueprint(main_bp)
from app.posts import bp as posts_bp
app.register_blueprint(posts_bp, url_prefix='/posts')
from app.questions import bp as questions_bp
app.register_blueprint(questions_bp, url_prefix='/questions')
@app.route('/test/')
def test_page():
return '<h1>Testing the Flask Application Factory Pattern</h1>'
return app
保存并关闭文件。
你将问题的蓝图注册方式和帖子的蓝图注册方式一样,给其路由添加/questions前缀。
在您的开发服务器运行时,使用您的浏览器导航到以下网址:
http://127.0.0.1:5000/questions/
页面上将显示问题和问题蓝图标题。
现在你需要让问题链接可用。打开基本模板来编辑导航栏。
nano app/templates/base.html
请使用以下内容修改