Skip to content

解读FlaskBB源码

Info

作者:Void,发布于2021-10-29,阅读时间:约3分钟,微信公众号文章链接:

1 前言

上回基于FlaskBB自建论坛说到FlaskBB是一个开源的功能强大的论坛,我们也已经成功地在本地运行了起来。不止于此,本文将带着大家解读FlaskBB的源码。

2 目录结构

我们首先来看看它的目录结构。

在根目录下,可以看到有常见的依赖相关的文件(requirements.txt,setup.py等),也有刚刚通过flaskbb makeconfig生成的flaskbb.cfg。tests文件夹存放了自动测试相关的代码。对于一个产品级的应用,自动测试是不可或缺的。
最后是主文件夹flaskbb。

3 源码解读

我们来看看flaskbb的主程序app.py中的create_app函数:

def create_app(config=None, instance_path=None):

    app = Flask(
        "flaskbb", instance_path=instance_path, instance_relative_config=True
    )

    # instance folders are not automatically created by flask
    if not os.path.exists(app.instance_path):
        os.makedirs(app.instance_path)

    configure_app(app, config)
    configure_celery_app(app, celery)
    configure_extensions(app)
    load_plugins(app)
    configure_blueprints(app)
    configure_template_filters(app)
    configure_context_processors(app)
    configure_before_handlers(app)
    configure_errorhandlers(app)
    configure_migrations(app)
    configure_translations(app)
    app.pluggy.hook.flaskbb_additional_setup(app=app, pluggy=app.pluggy)

    return app

在configure_app里FlaskBB首先加载了配置信息。FlaskBB会依次尝试从默认配置、用户配置和环境变量中导入配置信息。configure_extensions初始化了用到的相关Flask扩展。configure_blueprints初始化了Blueprint,包括user、forum、auth、management。以上四块内容挂载在不同的url下,它们是整个结构的四大重要板块。还有处理error的configure_errorhandlers,在Jinja2模板中添加过滤器的configure_template_filters等模块。

看完了最重要的app.py。我们可以看到同一目录下有刚刚提到的user、forum、auth、management四个文件夹。让我们来看看这四大板块是如何构造的。

我们打开user文件夹的models.py,这一文件定义了用户这一模块中,用户、群组等关系。这边需要提到一个对象关系映射(ORM,Object Relational Mapping)的概念。简单理解ORM是指用程序语言来定义的数据库。

class User(db.Model, UserMixin, CRUDMixin):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(200), unique=True, nullable=False)
    email = db.Column(db.String(200), unique=True, nullable=False)
    _password = db.Column('password', db.String(120), nullable=False)

字段的定义看上去比较直接,那么我们如何来定义关系呢?比如用户和主题的一对多关系。一个用户可能会发起多个主题。在User这个class下,我们可以看到有如下代码。

topics = db.relationship(
    "Topic",
    backref="user",
    primaryjoin="User.id == Topic.user_id",
    lazy="dynamic"
)

如此定义会在User中创建topics这一字段,也会在Topic这一表中创建user这一字段。连接查询时的条件为User.id == Topic.user_id。
代码中还定义了删除、保存等常规操作。

四大模块都有models,views,forms三个子模块。整体的结构是非常清晰的。和大部分Flask项目类似,html模板依然放在templates文件夹下,js,css,图片等放在static文件夹下。最开始提到的tests文件夹存放了自动测试的模块。

4 总结

通过FlaskBB的源码,我们学习了一个成熟的,产品级的项目的结构以及不同模块的内容。总体而言,它的代码非常工整、规范、可读性较强。我们可以在此基础之上,根据我们的需求魔改内容,使之成为一个真正可用的论坛产品。


Viewed times

Comments