一,上节回顾:
1) flask 最小应用代码。
from flask import Flask
app = Flask(__name__)
@app.route('/hello')
def hello():
return 'hello'
if __name__ == '__main__':
app.run()
2) flask 路由实现
@app.route('/') ,路由装饰器,本质上是调用app.add_url_rule() 方法实现的路由规则
3) flask 启动参数
host: 主机
port:端口
debug:是否开启调试模式
4) if __name__ == '__main__' 的理解
在本文件中启动 __name__ 就是 __main__
如果是导入其他模块 __name__ 就是 模块的名称
5) 视图函数和普通函数的区别?
普通函数:可以返回字符串,字典,元组,整型等基本数据类型
视图函数:返回的是Response对象,包括但不限于状态码(status_code),返回类型(Content-type)等
二,flask结构化拆分。
当我们有大量的业务代码的时候,就不能在一个index.py中书写了,因为这样臃肿且不易维护,而且都把代码放在一个文件中也不符合python之禅的精神,所以呢,我们需要对结构化进行一个拆分。
一般情况下会拆分成以下结构:
test 工程目录
app #应用层
config #配置目录
__init__.py #初始化文件
secure.py #机密配置
setting.py #普通配置
libs #库目录
helper.py #帮助方法模块
httper.py #网络请求模块
... #其他模块
models #模型目录
__init__.py #初始化文件
model.py #模型文件
... #其他文件
web #蓝图1目录
__init__.py #蓝图初始化文件
xxx.py #蓝图文件
... #其他文件
api #蓝图2目录
__init__.py #蓝图初始化文件
xxx.py #蓝图文件
... #其他文件
cms #蓝图3目录
__init__.py #蓝图初始化文件
xxx.py #蓝图文件
... #其他文件
static #静态文件夹
css #css文件夹
js #js文件夹
img #图片
font #字体
... #其他模块
templates #模版文件夹
xxxx #业务目录1
xxxx.html #业务模版
server.py 入口文件
三、那么我们现在开始进行结构化拆分之旅吧
1. 增加config.py
2. 在server.py中引入config配置文件
启动之后,debug调试模式开启,端口号由默认的5000更改成8000了。这也就是说我们导入的配置文件有效。
3. 在工程目录下创建一个user.py 文件
重新启动后,调用浏览器 http://127.0.0.1:8000/user
为什么会报404 Not Found 呢?是不是我们没有在server文件中引入user.py呢?那我们在sever.py中引入user.py
浏览器访问 http://127.0.0.1:8000/user
既然我在主文件中已经导入了user模块,那为什么还是不奏效呢? 这个就得从循环导入问题解决了,你觉得两次的app是一样的吗?我们做一个实验。
在server.py中 打印app的id, print('实例化的app',id(app))
在server.py中 main函数中打印 print('运行中的app',id(app))
在 user.py 中 打印 print('路由中的app',id(app))
运行之后:
事实说明flask实例化两次,走路由的那次app最终没有在main函数中执行,所以会报404错误。
解释:
0. 当启动程序之后,文档流自上之下执行,先进入server.py文件,导入flask模块
1. 我看见app = Flask(__name__) 实例化app , app获得一个地址app1
2. 继续向下执行,导入user模块
3. 我进入user模块
4. 在 user模块中,我遇见了 from server import app 这个导入
5. 那我在回到server 模块
6. 我又看见 app = Flask(__name__),那么app再次实例化,是不是这个app地址和上一次的不一样了?
7. 继续向下执行,看见 import user 了 ,还需要在进入user模块吗? 不需要了,因为模块只需导入一次。这样形成了一个循环导入
8. 这次过来 __name__ 是什么? 她是在user模块中过来的,那么__name__ 是不是 user ? 所以在user中的 from server import app 中的蓝线到此截至了。
9. 接着,我们走 app.route() 现在的这个app 是不是 app第二次实例化的地址?
10. 然后进入 server 中, __main__ 是不是 __main__ 因为这次是 import user之后,user全部走完后回来的,主体还是在server中完成的,那么 __name__ 就是 __main__
11. 进入 if 语句
12. app 是 第一次实例化的地址,启动程序。
这就是出现404的原因。因为实例化了两次,而路由所有的app地址最终没有进入if 主函数里 所以才会出现404的问题。