前面说那麽多次以後会遇到大型专案会怎样怎样的,所以现在就要来说一下大型专案长怎样,如何将大型专案拆解开来看,让你不会拿到一大包东西完全不知如何下手。
话说因为 Flask 本身就是小框架,也没太多重要的或常用的东西可以讲;再加上我是想把 Flask 本体讲完再讲其他的啦,所以这篇算是有关 Flask 本体的最後一篇了。下一篇就会进入到 Flask 插件的部分(是说上一篇其实就有讲到插件了)。
如果网站架构持续运作了好几年,中间不断地修修改改,功能越来越多,架构越来庞大,将全部的路由都放在一个档案里面会造成维护上的困难,所以势必要将不同功能的路由拆成不同档案,以利维护。
而 Blueprints 是 Flask 提供的将不同功能的路由模组化管理的方式,不过路由是分开了,那前端视图跟静态文件呢?
如果不做设定,前端视图跟静态文件还是在 templates
跟 static
里面,这样的优点是不同模组间能够套用同样的父视图(base.html
那个东东);而如果想要不同模组间可以有不同的视图,也能够分开摆放(也可以一部份分开,一部分放一起)。
那就直接来看如何使用吧。让我们拿前面的架构再来改一下:
ithome
├── account # 取个有意义的名字
│ └── api.py # 随便取个名字
├── static
│ └── logo.png
├── templates
│ ├── account # 它改个有意义的名字
│ │ ├── home.html
│ │ ├── login.html
│ │ └── settings.html
│ ├── base.html
│ ├── index.html
│ └── page_not_found.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
然後将 app.py
里面的 home, login, settings 搬进去 account -> api.py
里面,再各加上几行。
然後因为移动了 index.html
跟 page_not_found.html
,还有改了 res
的资料夹名称,所以有关 render_template
的都需要改一下;以及路由需要修正一下。
app.py
里面应该剩这样:
from flask import Flask, render_template, make_response
# 这个 app 是 api.py 里面的 app,建议改个有意义的名字,同样都叫 app 是我懒得改
# 如果名称冲突到,可以使用 as 来取个昵称。
from account.api import app as account
from configs import config
app = Flask(__name__)
app.config.from_object(config.DevelopmentConfig)
# 注册 blueprint
app.register_blueprint(account)
# 这边的 app 是上面 Flask 的 app
@ app.route('/')
def index():
return render_template('index.html')
''' 应该还有一些其他的东西,不过这里没有要用到,注解掉或删掉都没关系 '''
@ app.errorhandler(404)
def page_not_found(error):
response = make_response(render_template(
'page_not_found.html', error=error), 404)
return response
if __name__ == "__main__":
app.run()
前面的那三个路由搬到 api.py
里面,有关 render_template
的记得改一下。
# 新增这行
from flask import Blueprint, redirect, request, render_template, make_response, url_for
# 还有新增这行,同样叫 app 只是我懒得改,建议还是改有意义的名字。
app = Blueprint('account', __name__)
@app.route('/home', methods=['GET'])
def home():
if 'username' in request.cookies:
user = request.cookies.get('username')
return render_template('account/home.html', username=user)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
response = make_response(render_template('account/login.html'))
elif request.method == 'POST': # 表单送出後会到这里
account = request.values.get('username', None)
# 验证是否有这个使用者以及密码是否正确,生出验证结果 auth_result
auth_result = 'success' # 假设成功
''' 建立回应 '''
if auth_result == 'success': # 如果都正确
response = make_response(redirect(url_for('account.home')))
response.set_cookie('username', account) # 先使用 Cookie 就好
else: # 如果错误
response = make_response(redirect(url_for('account.login')))
else:
response = make_response(redirect(url_for('index')))
return response
@app.route('/settings', methods=['GET'])
def settings():
if 'username' in request.cookies:
user = request.cookies.get('username')
return render_template('account/settings.html', username=user)
改到这里就差不多了,如果在 .html
里面有使用到 url_for
的要记得改一下。例如 url_for('login')
要改成 url_for('account.login')
,前面加 Blueprint 中的第一个参数还有英文句号就 OK 了(还有不是那个 Blueprint 下的路由前面不要乱给他加名称,不要乱认亲)。
如果要改的都有改到的话,这几个功能应该跟移动之前是差不多的,不过这几个功能就分开来了,在维护时也能更快、更轻松的维护。
如果要将前端视图与静态文件分开,首先至少要将它们搬到相应的位置对吧。
ithome
├── account
│ ├── static_account
│ │ └── logo.png
│ ├── templates_account
│ │ ├── account # 因为我不想改 render_template,所以就留着它了。
│ │ │ ├── home.html
│ │ │ ├── login.html
│ │ │ └── settings.html
│ │ └── base.html
│ └── api.py
├── static
│ └── logo.png
├── templates
│ ├── base.html
│ ├── index.html
│ └── page_not_found.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
搬完之後,再到 api.py
设定新的前端视图与静态文件位置,
api.py
from flask import Blueprint, redirect, request, render_template, make_response, url_for
app = Blueprint('account', __name__, static_folder='static_account',
static_url_path='/img', template_folder='templates_account',
url_prefix='/account')
@app.route('/home', methods=['GET'])
def home():
if 'username' in request.cookies:
user = request.cookies.get('username')
return render_template('account/home.html', username=user)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
response = make_response(render_template('account/login.html'))
elif request.method == 'POST': # 表单送出後会到这里
account = request.values.get('username', None)
# 验证是否有这个使用者以及密码是否正确,生出验证结果 auth_result
auth_result = 'success' # 假设成功
''' 建立回应 '''
if auth_result == 'success': # 如果都正确
response = make_response(redirect(url_for('account.home')))
response.set_cookie('username', account) # 先使用 Cookie 就好
else: # 如果错误
response = make_response(redirect(url_for('account.login')))
else:
response = make_response(redirect(url_for('index')))
return response
@app.route('/settings', methods=['GET'])
def settings():
if 'username' in request.cookies:
user = request.cookies.get('username')
return render_template('account/settings.html', username=user)
Blueprint 一样有着 static_folder
、 static_url_path
、 template_folder
,用法也跟 Day 17 一样。而 url_prefix
是什麽呢?
先来看看不加 url_prefix
会发生什麽事。
再来看看加了 url_prefix
会发生什麽事。
有注意到 url 的变化吗?就是在这个 Blueprint 里面的路由都加上 url 前缀。
那麽就大概这样,有关 Flask 本体大概就这样就结束了,下一篇开始就是 Flask 的插件了。
大家掰~掰~
<<: Day23 - 将台湾证券交易所的每日收盘行情存入 DB
>>: Day21-TypeScript(TS)的函式(Function) Part1
我使用Anaconda帮我们管理套件以及不同的开发环境,让程序码可以在特定套件下执行,还可以在不同环...
**Actual Oracle 1Z0-082 Practice Exam - Easiest Wa...
在开始之前,还是很惊讶自己有天可以在这里写文章,分享自身所学的IT技术,提供给大家参考。那其实我...
这篇文章会介绍利用CSS定位的属性来控制html元素的位置,在之前的文章中有利用过padding和m...
MTR是Linux平台上一款非常好用的网络诊断工具,或者说网络连通性判断工具,集成了tracerou...