kuxingseng95

通常一个项目的启动文件为app.py或者manage.py,所以我们先将项目中启动文件的文件名进行修改。这里我修改为manage.py。

在立项准备的时候,我们在manage.py中写入了太多的内容,导致整个文件已经非常的臃肿了,所以,这里我们要对代码进行抽取,我们只让manage.py做一个程序的启动入口,而不是让所有代码都写入其中。

这里,我们自顶向下开始抽取。

第一步:配置文件抽取

1.在项目目录下新建config.py

2.将配置类从manage.py中拿到config.py中。(原来的代码不要直接剪切,复制到新文件中,然后将原来的注释掉,防止改错)

3.哪里报错改哪里

config.py

from redis import StrictRedis

manage.py

from config import Config

 

补充说明

封装代码的步骤:

  1. 确定哪些代码需要封装
  2. 确定要封装到哪里
  3. 将代码移动到指定位置
  4. 回看是否有错
  5. 如果有错就改错
  6. 改错后直接运行
  7. 注意点
    • 切记不要一次封装太多代码
    • 如果逻辑复杂,分批逐步封装

 

 第二步:抽取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(烧脑的东西)

这里专门解释下为啥要用工厂方式来创建app,因为app的相关信息的修改和业务逻辑有关。而你们公司会有个恶心的职业,叫做测试,每当我们修改了业务逻辑的相关内容,都必须要进行测试,哪怕只是加了个空格,改了标点也要重新测试(没错,就是这么恶心)。所以,你懂的!

而目前和业务逻辑无关的是manage.py和config.py我们要看看从哪个文件入手,来间接地处理这个问题,这里我们选择的是manage.py。

1.创造创建app的函数

info -> __init__.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from redis import StrictRedis
from flask_wtf.csrf import CSRFProtect
from flask_session import Session
from config import Config, DevlopmentConfig, ProductionConfig, UnittestConfig


def create_app(config_name):
    """创建app的工厂方法
    参数:根据参数选择不同的配置类
    """
    app = Flask(__name__)

    # 获取配置信息
    app.config.from_object(config_name)

    # 创建连接到MySQL数据库的对象
    db = SQLAlchemy(app)

    # 创建连接到Redis数据库的对象
    redis_store = StrictRedis(host=config_name.REDIS_HOST, port=config_name.REDIS_PORT)

    # 开启CSRF保护:因为项目中的表单不再使用FlaskForm来实现,所以不会自动地开启CSRF保护,需要我们自己开启
    CSRFProtect(app)

    # 指定session存储在后端的位置
    Session(app)

当我们这么玩的时候,manage.py中的app和db导包的时候发生了错误,这是因为我们把这部分内容放到了函数中,尴尬的是,这样我们就没法从__init__中读取这两个内容了。这里先不用解决,放着就好。

 

2. 在manage.py中使用之前定义的创建app的函数来创建app

 

现在有两个问题需要解决:

一个是db,这个东西目前解决不了,先给它注释掉,别让它报错了。

还有一个是app,这个我们可以使用之前的函数来创建,而在函数中,我们指定了一个接收参数来指定配置环境,这个怎么完成呢?

这里给大家提供一种思路。

配置信息的相关设置在config.py中,所以在这个文件中定义一个字典,存储关键字对应的不同的配置类的类名

# 定义字典,存储关键字对应的不同的配置类的类名
configs = {
    \'dev\': DevlopmentConfig,
    \'pro\': ProductionConfig,
    \'unit\': UnittestConfig
}

 那么在创建app的时候,我们就可以加入这个参数了。

manage.py

# 创建app
app = create_app("dev")

 

好了,参数传到了__init__中去创建app了。但是__init__中并不知道这个参数的作用,所以需要导入相关包,并完成相关配置:

 

 

好了,大概搞完了,运行一下看看吧!

测试之后,会发现报了下面的错误:

 

 这个问题,一般来说你是找不到了,直接告诉你。我们在写创造app的工厂函数的时候,配置了一堆东西,作用是干嘛?不就是造一个app吗?你造完了之后返回了吗?

所以,在工厂函数的后面加上:

return app

 

这次应该就没有毛病了! 

 

 第五步:设置全局db

 在前面,解决工厂函数的问题的时候,为了不报错,我们将db给注释了,还记得没?这是”病“不能拖,我们开始“治病”。

 想要解决db的问题,第一个要点就是能看懂源代码!所以,我们从源代码来分析解决的方法。

 CTRL+左键,点下面的,我们开始看源码:

 初始化app,不知道是啥? CTRL+左键,点进去。

 

 这里面恰好要从app的相关配置中读取数据库的连接信息。所以,我们没有传入app的话,就创建不了连接到MySQL数据库的对象。也就是说,我们只要调用这个init_app初始化函数,并将app传进去就完事了。

    ....
# 创建SQLAlchemy对象
db = SQLAlchemy()

def create_app(config_name):
    """创建app的工厂方法
    参数:根据参数选择不同的配置类
    """

    ....

    # 创建连接到MySQL数据库的对象
    # db = SQLAlchemy(app)
    db.init_app(app)

    ....

再把manage.py中的注释打开,测试一下代码吧!

分类:

技术点:

相关文章:

  • 2022-01-18
  • 2021-08-31
  • 2021-11-28
  • 2021-10-12
  • 2021-12-19
  • 2022-02-09
  • 2022-02-22
猜你喜欢
  • 2021-12-08
  • 2021-04-02
  • 2021-09-04
  • 2021-06-22
  • 2021-04-20
  • 2021-12-13
  • 2021-07-09
相关资源
相似解决方案