1.Flask教程

源地址: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数据库文件存储在实例目录下。
[email protected]()创建一个简单的路由,这样你可以在进入教程其他部分之前看到一个可运行的应用。在这个例子中,应用创建了一个指向/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教程)