新闻详情——项目准备
第一步:配置文件抽取
第一步:配置文件抽取
1.在项目目录下新建config.py
2.将配置类从manage.py中拿到config.py中。(原来的代码不要直接剪切,复制到新文件中,然后将原来的注释掉,防止改错)
3.哪里报错改哪里
config.py
from redis import StrictRedis
manage.py
from config import Config
补充说明
封装代码的步骤:
- 确定哪些代码需要封装
- 确定要封装到哪里
- 将代码移动到指定位置
- 回看是否有错
- 如果有错就改错
- 改错后直接运行
- 注意点
- 切记不要一次封装太多代码
- 如果逻辑复杂,分批逐步封装
第二步:抽取app
我们的目的是让manage.py成为程序的入口,所以,这里在manage.py中的相关app设置,我们也要进行抽取。
app的抽取,我们只抽取标注的部分,因为我们启动用的是manage.py,而后面的部分和manage有很多的联系,抽取反而带来麻烦。
其实,app的相关代码都是业务逻辑相关代码,所以,我们最好将其封装到业务逻辑部分中。
这里,我们需要新建一个Python Package的包,命名为info,以后里面就存储着业务逻辑相关代码。
这里,我们将标注的部分抽取到info的__init__中,因为业务逻辑只要一开始,就会优先执行__init__文件中的内容。
当把代码放入到__init__中,可以看到下面内容:
一堆包需要导入,是不是满头包了啊!其实让大家抽取的时候注释原来的代码还有个好处,就是方便收集导包信息,我们将那些注释后变灰的导包代码都收集起来,同意放到__init__中,这样会方便很多。
__init__中的导包问题解决之后,我们来解决manage.py中的导包问题。
manage.py
from info import app, db
到目前位置,封装的差不多了,我们再次运行代码,看看是否可以正常运行。
第三步:抽取不同环境下的配置
不同开发环境会有不同的配置,所以我们要封装不同开发环境下的配置信息。
config.py
# 以下代码是封装不同开发环境下的配置信息 class DevlopmentConfig(Config): """开发环境""" pass # 开发环境与父类基本一致 class ProductionConfig(Config): """生产环境""" DEBUG = False SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1:3306/production_news_data' class UnittestConfig(Config): """测试环境""" pass
这里定义了三个类,它们都继承自我们定义的Config配置类,我们可以在里面对配置类中的相关信息进行重写。
重写之后,就可以去info中的__info__修改指定的配置类:
但是!这个封装有瑕疵,我们经常要根据不用的运行环境来修改配置信息,而这些东西改的太多,有时候会忘记,所以,还需要更进一步的处理,这也是下一步要完成的内容。
第四步:工厂方式建立app
from flask import Flask from flask_sqlalchemy import SQLAlchemy from redis import StrictRedis from flask_session import Session from config import DevelopmentConfig,ProductionConfig,UnittestConfig def create_app(env): """创建app的工厂方法 参数:根据参数选择不同的配置类 """ app = Flask(__name__) #创建app app.config.from_object(DevelopmentConfig) #指定配置类 db = SQLAlchemy(app) #创建连接到mysql数据库的对象 redis_store = StrictRedis(host = DevelopmentConfig.REDIS_HOST,port = DevelopmentConfig.REDIS_PORT) #创建连接到redis数据库的对象 Session(app) #指定session存储在后端的位置
当我们这么写的时候,manage.py会报红,这是因为我们把app,db放在了函数里面
我们在manage.py中使用之前创建app的函数来创建app
这里db还是报错,我们先把他注释掉,不让他报错了
我们用创建app的函数创建app,但是我们制定参数来接受配置环境,这个要在confing里面完成,在里面定义一个字典,存储键对应的不同的配置信息
#定义字典,存储键对应的不同的配置信息
configs = {
"dev": DevelopmentConfig,
"pro": ProductionConfig,
"uni": UnittestConfig
}
那么在创建app的时候,就可以加入参数了
app = create_app("dev")
参数传到__init__中去创建app了,但是__init__并不知道它的作用,我们需要导入相关包
写完之后运行一遍会发现报错。那是因为我们写创造app的工厂函数,配置了一堆东西,但是没有返回
在工厂函数的后面加上
return app
第五步:设置全局db
之前我们工方法创建app时,把db给注释了,现在我们来处理这个问题
我们先看一下源码
进入源码里面
不知道初始化app是什么的,Ctrl加左键点进去
这里恰好要从app的相关配置中读取数据库的连接信息,如果没有传入app,就创建不了连接到MySQL数据库的对象,所以,这里使用init_app这个初始化函数,并将app传进去就完了
db = SQLAlchemy() def create_app(env): """创建app的工厂方法 参数:根据参数选择不同的配置类 """ app = Flask(__name__) #创建app app.config.from_object(configs[env]) #指定配置类 db.init_app(app) redis_store = StrictRedis(host = configs[env].REDIS_HOST,port = configs[env].REDIS_PORT) #创建连接到redis数据库的对象 Session(app) #指定session存储在后端的位置 return app
第五步:日志的集成
logging模块的使用方式
# 设置日志的记录等级 logging.basicConfig(level=logging.DEBUG) # 调试debug级 # 创建日志记录器,指明日志保存的路径(前面的logs为文件的名字,需要我们手动创建,后面则会自动创建)、每个日志文件的最大大小、保存的日志文件个数上限。 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)
- loggers 提供应用程序代码直接使用的接口
- handlers 用于将日志记录发送到指定的目的位置
- filters 提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出(其它的日志记录将会被忽略)
- formatters 用于控制日志信息的最终输出格式
第一步:日志的基本集成
import logging from logging.handlers import RotatingFileHandler # 设置日志的记录等级 logging.basicConfig(level=logging.DEBUG) # 调试debug级 # 创建日志记录器,指明日志保存的路径(前面的logs为文件的名字,需要我们手动创建,后面则会自动创建)、每个日志文件的最大大小、保存的日志文件个数上限。 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) db = SQLAlchemy()
运行之后发现报错了:
这是我们忘记在项目路径下面创建存放日志的文件,在项目路径下创建logs文件夹来存储日志相关类容
再次运行就可以了
第二步:根据配置信息封装日志
这里日志有不同的等级和创建不同配置app一样,我们可以向创建app工厂一样写
在工厂函数下,调用setup_log函数
图片里的setup_log(configs[env].LEVEL_LOG)和我们获取配置信息时定义的方式一样
第三步:在配置类中加入日至等级的类属性
class DevelopmentConfig(Config): "开发环境" #开发环境日志等级 LEVEL_LOG = logging.DEBUG class ProductionConfig(Config): "生产环境" DEBUG = False SQLALCHEMY_DATABASE_URI = "mysql://root@127.0.0.1:3306/demo" #生产环境日志等级 LEVEL_LOG = logging.ERROR class UnittestConfig(Config): "测试环境" pass