1.Flask教程

作者: 风吹柳_柳随风 | 来源:发表于2018-08-14 16:54 被阅读0次

    源地址:http://flask.pocoo.org/docs/1.0/tutorial/

    1.1.项目布局

            创建一个项目目录并进入:

    mkdir flask-tutorial
    cd flask-tutorial

            然后跟着installation instructions建立一个python虚拟环境和安装Flask环境。
            该教程假设你从现在开始都是在flask-tutorial目录下进行操作的。在代码片段最上方的文件名称都是相对于该目录的。


            一个Flask应用可以简单到只有一个文件:
    hello.py

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return 'Hello, World!'
    

            然而随着项目越做越大,将所有的代码放到一个文件中显然是不合理的。我们可以使用包将不同的模块分隔开来,如果哪需要用到这个模块,就进行模块的引入。当然,这教程也是这种做法。
            该项目将包含以下几项:

    • flaskr/,包含你应用代码与文件的python目录。
    • tests/,包含测试模块的目录。
    • venv/,安装Flask及其依赖包的python虚拟环境。
    • 安装文件告诉Python如何安装你的项目。
    • 版本控制文件,例如 git。你应该养成对你所有的项目进行版本控制的习惯。
    • 将来你会添加的项目文件。
              最后,你的项目布局看起应该是这样:

    /home/user/Projects/flask-tutorial
    ├── flaskr/
    │ ├── init.py
    │ ├── db.py
    │ ├── schema.sql
    │ ├── auth.py
    │ ├── blog.py
    │ ├── templates/
    │ │ ├── base.html
    │ │ ├── auth/
    │ │ │ ├── login.html
    │ │ │ └── register.html
    │ │ └── blog/
    │ │ ├── create.html
    │ │ ├── index.html
    │ │ └── update.html
    │ └── static/
    │ └── style.css
    ├── tests/
    │ ├── conftest.py
    │ ├── data.sql
    │ ├── test_factory.py
    │ ├── test_db.py
    │ ├── test_auth.py
    │ └── test_blog.py
    ├── venv/
    ├── setup.py
    └── MANIFEST.in

    1.2.设置应用程序

            一个Flask应用就是一个Flask类的实例。所有有关应用的一切,例如配置和URLS,都要注册到这个类中。
            创建Flask应用程序最直接的方法是直接在代码顶部创建一个全局的Flask实例。对于某些情况,这是一个行之有效的方式,但随着项目的增长,它可能会导致一些棘手的问题。
            你可以在一个方法中创建Flask实例来代替创建全局的Flask实例。这个方法被称为工厂方法。所有的配置,注册和其他需要初始化都在一个方法中进行处理,然后返回初始化好的实例。

    1.2.1.应用的工厂化方法

            是时候进行编码啦!创建flaskr目录并添加__init__.py文件。__init__.py承担两个职责:1.它包含了应用的工厂方法。2.告诉Python解析器,flaskr目录当成一个Python包来处理。

    mkdir flaskr
    

    flaskr/__init__.py

    import os
    
    from flask import Flask
    
    def create_app(test_config=None):
        # create and configure the app
        app = Flask(__name__, instance_relative_config=True)
        app.config.from_mapping(
            SECRET_KEY='dev',
            DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
        )
        
        if test_config is None:
            # load the instance config, if it exists, when not testing
            app.config.from_pyfile('config.py', silent=True)
        else:
            # load the test config if passed in
            app.config.from_mapping(test_config)
        # ensure the instance folder exists
        try:
            os.makedirs(app.instance_path)
        except OSError:
            pass
        
        # a simple page that says hello
        @app.route('/hello')
        def hello():
            return 'Hello, World!'
        
        return app
    

            create_app是这个应用的工厂方法。你将在教程的后面继续添加它的逻辑,但它已经做了很多事情。
    1.app = Flask(__name__, instance_relative_config=True)创建Flask实例。

    • __name__指的是当前Python模块的名称。该app需要知道它所在的位置从而设置一些路径,__name__参数就很便利。
    • instance_relative_config=True告诉app配置文件是相对于实例文件夹的。实例文件是位于flaskr包的外部,它可以保存不被版本控制的本地数据,例如密钥配置和数据库语句。

    2.app.config.from_mapping()设置一些app将会使用的默认配置:

    • SECRET_KEY被Flask和插件用于加密,保证数据的安全。在开发过程中,FLask给我们提供了一个便利的值'dev',当发布时,该值应该被一个随机值覆写。
    • DATABASE指定了存放SQLite数据库文件的路径。它是在app.instance_path路径下,app.instance_path是Flask指定的实例目录。在下一章节会讲述更多的关于数据库的内容。

    3.app.config.from_pyfile()会使用实例文件夹下的config.py(如果存在)文件中的值覆盖默认配置。举个例子,当发布时,这个函数可以用来设置一个真实的SECRET_KEY

    • test_config也可以传递给工厂,并且将会被用于替换实例配置。在这个教程后面点你将会写到的单元测试能够被单独配置——独立于任何配置的开发值。

    4.os.makedirs()主要是确认app.instance_path是否存在。Flask不会自动地创建实例目录,但是实例文件确实需要创建,因为你要将你的SQLite数据库文件存储在实例目录下。
    5.@app.route()创建一个简单的路由,这样你可以在进入教程其他部分之前看到一个可运行的应用。在这个例子中,应用创建了一个指向/hellourl的连接和一个返回字符串'Hello, World!'响应的方法。

    1.2.2.启动应用程序

            现在你可以使用flask命令来启动应用。在终端告诉Flask在哪能找到你的应用,并以开发环境的模式启动它。
            无论何时一个页面抛出异常的时候,开发模式都会显示交互式的调式器。无论何时你修改了项目代码,开发模式都会重启服务。你可以让它保持运行,只需按照教程重新加载浏览器页面即可。
    对于Linux和Mac系统:

    export FLASK_APP=flaskr
    export FLASK_ENV=development
    flask run

    对于Windows命令行,使用set替代export

    set FLASK_APP=flaskr
    set FLASK_ENV=development
    flask run

    你将会看到控制台的输出大致如下:

    * Serving Flask app "flaskr"
    * Environment: development
    * Debug mode: on
    * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    * Restarting with stat
    * Debugger is active!
    * Debugger PIN: 855-212-761

            在浏览器中访问http://127.0.0.1:5000/hello,你应该能够看到 “Hello, World!” 信息。恭喜你,你正在运行你自己的Flask网络应用。

    1.3.定义和访问数据库

            该应用将会使用SQLite数据库来存储用户与请求数据。Python在sqlite3模块中内置了对SQLite的支持。
            SQLite非常便利,因为它不需要额外的分离的数据库服务并且它是内置在Python中。然而,在同一时间,多个并发请求同时试图将数据写入数据库,请求响应时间将会延长,因为每次写入都是顺序发生的。小应用不会注重这些。一旦你的应用变大,你可能希望切换到其他数据库。
            该教程不会详细介绍SQL语句。如果你不熟悉它,你可以在SQLite文档中找到该语言的描述。

    1.3.1.连接数据库

            当你想操作一个SQLite数据库,首先你要做的是创建一个SQLite连接。所有的查询与操作都是基于这个连接的。当完成任务后,记得关闭这个连接。
            在一个网络应用中,一个连接通常对应一个请求。一般是在处理请求时的某个阶段创建连接,然后在发送响应之前关闭这个连接。
    flaskr/db.py

    import sqlite3
    
    import click
    from flask import current_app, g
    from flask.cli import with_appcontext
    
    def get_db():
        if 'db' not in g:
            g.db = sqlite3.connect(
                current_app.config['DATABASE'],
                detect_types=sqlite3.PARSE_DECLTYPES
            )
            g.db.row_factory = sqlite3.Row
    
        return g.db
    
    def close_db(e=None):
        db = g.pop('db', None)
    
        if db is not None:
            db.close()
    

            g是一个特殊的对象,对于每一个请求,它都是唯一的。在一个请求中,多个方法都有权访问g存储的数据。连接被保存在g中,如果在同一个请求中,get_db方法被调用第二次,那么连接将会被重用而不是重新创建一个新的连接。
            current_app是另一个特殊的对象,它指向当前处理这个请求的Flask应用。由于你使用的是应用程序工厂,因此在编写其余代码时没有应用程序对象,current_app就是这个应用程序对象。当应用已经被创建开始处理请求时,get_db将会被调用,这里使用current_app获取配置信息。
            sqlite3.connect()与指向DATABASE配置键的文件建立起一个数据库连接。此文件当前还不存在,直到你初始化数据库之后才会出现。
            sqlite3.Row告诉连接返回像字典数据形式的行。这样可以通过列名进行访问数据。
            close_db函数检查是否在g.db对象中创建出来的连接是否存在。如果连接存在,它就关闭这个连接。你将在应用工厂中告诉你的应用有关close_db函数,以便在每个请求之后它能够被调用。

    1.3.2.创建表

            在SQLite数据中,数据是存储在表或列中。在存储和查看数据之前,你需要先创建表。Flaskr将在user表中存储用户信息,在post表中存储请求信息。创建包含创建空表sql语句的文件:
    flaskr/schema.sql

    DROP TABLE IF EXISTS user;
    DROP TABLE IF EXISTS post;
    
    CREATE TABLE user (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT UNIQUE NOT NULL,
        password TEXT NOT NULL
    );
    
    CREATE TABLE post (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        author_id INTEGER NOT NULL,
        created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        title TEXT NOT NULL,
        body TEXT NOT NULL,
        FOREIGN KEY (author_id) REFERENCES user (id)
    );
    

            在db.py文件中添加运行这些sql命令的Python函数。
    flaskr/db.py

    def init_db():
        db = get_db()
    
        with current_app.open_resource('schema.sql') as f:
            db.executescript(f.read().decode('utf8'))
    
    @click.command('init-db')
    @with_appcontext
    def init_db_command():
        """Clear the existing data and create new tables."""
        init_db()
        click.echo('Initialized the database.')
    

            open_resource()打开一个相对于flaskr目录的文件。这个方法非常有用——当你不知道你项目路径时,可以使用该方法获取对应的项目文件。get_db方法返回一个用于执行sql命令的数据库连接。
            click.command()定义了一个名为init-db的命令行命令。该命令行的功能主要是调用上面定义的init_db函数并给用户展示一个数据库初始化成功的信息。你可以阅读 Command Line Interface来了解如何编写命令。

    1.3.3.注册到应用中

            close_dbinit_db_command函数需要被注册到应用实例中,否则它们不能在应用中使用。然而由于你使用了工厂函数,当你在写这些函数时,应用实例你还获取不到。取而代之的方式是写一个提出申请并进行注册的函数。
    flaskr/db.py

        def init_app(app):
            app.cli.add_command(init_db_command)
            app.teardown_appcontext(close_db)
    

            app.teardown_appcontext()告诉Flask当返回响应时调用注册的方法进行清理。
            app.cli.add_command()添加一个新的能被flask命令调用的命令。
            在工厂中导入和调用该函数。在工厂函数之后,返回app之前编写新的代码:
    flaskr/__init__.py

    def create_app():
        app = ...
    
        # existing code omitted
    
        from . import db
        db.init_app(app)
    
        return app
    

    1.3.4.初始化数据库文件

            现在,init-db命令已经注册到app中了,你可以使用flask命令调用它,类似与前面说的run命令。

    注意:
            如果你还运行着前面的服务,你要么停止该服务,要么就新启一个命令行终端。如果你新启一个命令行终端,记得切换到项目目录,并且激活Activate the environment这里的环境。你同样需要设置前面提到的FLASK_APPFLASK_ENV这两个环境变量。

            运行init-db命令:

    flask init-db
    Initialized the database.
    

    现在,在你工程的实例目录下应该有一个名为flaskr.sqlite的文件。


    看得累了,敲代码去了,有空继续更

    相关文章

      网友评论

        本文标题:1.Flask教程

        本文链接:https://www.haomeiwen.com/subject/tpdmbftx.html