- 创建app函数和日志的设置
- 蓝图
- 项目执行流程
创建app函数和日志的设置
1.在Config类中加一个日志级别设置:
'''日志级别'''
LEVEL = logging.DEBUG
这相当于默认级别。
在下边的三个模式类中可以重写这个LEVEL变量。
例如:
ProductConfig类:
#生产环境
class ProductConfig(Config):
DEBUG = False
LEVEL = logging.ERROR #覆盖父类中的LEVEL
2.在news_info/init.py中编写函数
create_app():
'''创建app的方法'''
def create_app(config_name):
'''通过传入不同的配置名,切换不同的环境'''
app = Flask(__name__) # 获取app实例
# 根据传进来的config_name以字典方式获取对应的类
config = config_dict.get(config_name)
# 关联config类中的配置
app.config.from_object(config)
# 根据config类中的LEVEL设置日志级别,由于继承父类Config,默认为DEBUG
log_file(config.LEVEL)
# 初始化redis配置
redis.StrictRedis(host=Config.RDIES_HOST,port=Config.RDIES_PORT)
# 开启csrf保护,只用于服务器验 证
CSRFProtect(app)
# 设置session保存位置
Session(app)
return app
log_file():
'''记录日志'''
def log_file(level):
'''根据传进来的level进行操作'''
# 设置日志的记录等级,常见等级有: DEBUG<INFO<WARING<ERROR
logging.basicConfig(level=level) # 调试debug级
# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
file_log_handler = RotatingFileHandler("logs/log", maxBytes=1024 * 1024 * 100, backupCount=10)
# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
# 为刚创建的日志记录器设置日志记录格式
file_log_handler.setFormatter(formatter)
# 为全局的日志工具对象(flask app使用的)添加日志记录器
logging.getLogger().addHandler(file_log_handler)
写到这时,manage.py中会报出app,db的错误,因为manage.py中有用到init中的内容。
3.修改manage.py,由于我们在init.py中写了创建app的函数,那么直接将函数导进来,在manage.py中创建即可。
1.导入函数和db
from newsInfo import app,db
更换为
from newsInfo import create_app,db
2。调用函数,创建app
app = create_app('develop')
4.新建logs目录。
运行:
在logs文件下生成了log日志文件:
提交github时,不要把log日志文件提交上去,
修改方法:
在.gitignore文件中加上:
logs/*
这时在GitHub Desktop上就没有了logs了
蓝图
存在问题
我们学习Flask框架,是从写单个文件,执行hello world开始的。我们在这单个文件中可以定义路由、视图函数、定义模型等等。但这显然存在一个问题:随着业务代码的增加,将所有代码都放在单个程序文件中,是非常不合适的。这不仅会让代码阅读变得困难,而且会给后期维护带来麻烦,我们在一个文件中写入多个路由,这会使代码维护变得困难。
一个程序执行文件中,功能代码过多。就是让代码模块化。根据具体不同功能模块的实现,划分成不同的分类,降低各功能模块之间的耦合度。python中的模块制作和导入就是基于实现功能模块的封装的需求。
尝试用模块导入的方式解决: 我们把上述一个py文件的多个路由视图函数给拆成两个文件:app.py和admin.py文件。app.py文件作为程序启动文件,因为admin文件没有应用程序实例app,在admin文件中要使用app.route路由装饰器,需要把app.py文件的app导入到admin.py文件中。
上述的方法是不可取的。在python中切记不要互相导入。
也就是说,flask中提供一种能使代码更模块化,分层化的一个东西--蓝图,在之前的django中本身就已经将各个模块分开了,每一个模块负责网站的一块内容。
什么是蓝图?
蓝图:用于实现单个应用的视图、模板、静态文件的集合。
蓝图就是模块化处理的类。
简单来说,蓝图就是一个存储操作路由映射方法的容器,主要用来实现客户端请求和URL相互关联的功能。 在Flask中,使用蓝图可以帮助我们实现模块化应用的功能。
蓝图的运行机制:
蓝图是保存了一组将来可以在应用对象上执行的操作。注册路由就是一种操作,当在程序实例上调用route装饰器注册路由时,这个操作将修改对象的url_map路由映射列表。当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项。当执行应用对象的 register_blueprint() 方法时,应用对象从蓝图对象的 defered_functions 列表中取出每一项,即调用应用对象的 add_url_rule() 方法,这将会修改程序实例的路由映射列表。
蓝图的使用
1.导入蓝图
from flask import Blueprint
2.创建蓝图对象
#创建蓝图对象
name:蓝图的名称,import_name:获取当前模块
users = Blueprint(name='user',import_name=__name__)
3.注册蓝图路由,也就是在该模块中的视图函数
@users.route('/user1')
def user():
return '/user/user1'
4.将每个模块的蓝图对象注册到程序的入口文件中
首先要导入蓝图对象,blueprint:蓝图对象,url_prefix:该蓝图的起始url地址(类似于django中某个模块的总url)
app.register_blueprint(blueprint=users,url_prefix = '/user')
实例:
程序入口:
test.py:
from flask import Flask
from user import users #导入蓝图对象
from admin import admins
app = Flask(__name__)
#注册蓝图
app.register_blueprint(blueprint=users,url_prefix = '/user')
app.register_blueprint(blueprint=admins,url_prefix = '/admin')
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
user.py:
from flask import Blueprint
#创建蓝图
users = Blueprint(name='use',import_name=__name__)
#注册蓝图路由
@users.route('/user1')
def user():
return '/user/user1'
admin.py:
from flask import Blueprint
#创建蓝图
admins = Blueprint(name='admin',import_name=__name__)
@admins.route('/admin1')
def admin():
return '/admin/admin1'
运行:
注意:在使用蓝图时有可能会报出如下错误:
这是由于某个蓝图中的视图函数名于flask中相冲突,修改为其他的名称即可。
项目中的蓝图
在实际项目开发中,蓝图的使用没有在demo中的那么简单,因为项目的分层相对清晰,包之间层层嵌套。
在项目中蓝图的使用步骤:
1.在整个项目的app包(newsInfo)新建package--modelus,modelus负责整个项目的某个模块的操作。
2.在modelus模块中新建index包,负责首页的展示部分。在index包下新建views.py文件,
具体的包目录如下:
3.在index包下
- init.py:该index包下操作的初始化,也就是负责蓝图的创建
- views.py:负责init下蓝图视图函数的编写
index/init.py:
from flask import Blueprint
#创建蓝图
index_blue = Blueprint('index',__name__)
#导入本包下的views
from . import views
index/views.py:
#视图
from . import index_blue #导入__init__.py下的蓝图对象index_blue
#为该蓝图编写视图函数
@index_blue.route('/index1')
def index():
return '/index/index1'
4.在app实例下注册蓝图
也就是创建app时,就把所创建的蓝图加进去
这应该加在create_app函数中;
#在创建app时注册蓝图,尽量把导入和注册写在一起
from newsInfo.modules.index import index_blue
app.register_blueprint(index_blue,url_prefix = '/index')
注意:在创建app时注册蓝图,尽量把导入和注册写在一起
运行:
蓝图在项目执行的流程
在了解蓝图之后首先要了解整个项目以及app管理包(newsInfo)的目录结构和运行流程:
1.接下来走newsInfo包,因为app = Flask(name)在init.py下,先进入init初始化:
创建app的函数:获取app实例,关联Config配置,开启csrf保护,设置session,日志调用等操作。还有编写日志函数。
2.首先项目最先走的时manage.py中:
在这里执行的是调用创建app对象的函数创建app,管理app-manager,以及数据库的迁移。
3.在进入下一个模块index,首先进入init.py下:创建蓝图,根据蓝图对象在views.py中寻找该蓝图的视图函数。
网友评论