使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能

 

 

Flask 中文文档

Flask_Login 文档

Flask-sqlalchemy 文档

Jinja2 模板文档

 为了熟悉 Python 的 Web 开发,找到这个框架。在这里记录下使用它来写一个简单的登录 Demo 功能过程中碰到的问题。

上面几个链接就是使用到相关的库的文档。

Flask_Login 这个是官方实现的一套登录验证的库。

Flask_sqlalchemy 是官方对 sqlalchemy 库的一个封装,它是一个ORM,用于做数据库访问。

 

这里使用的开发工具是 PyCharm,使用这个工具可以直接创建一个 Flask 的项目。

 一、从一个简单的示例说起

创建一个 run.py 的代码文件存放在项目的根目录下。

run.py

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

这是官方文档上的一个最简单能直接运行的应用了

这里要注意的有两个地方:

1.@app.route('/')

这里定义的是一个完整的路由,也就是说,现在这里定义的是“/”,则真实访问的地址就是首页。

2.app 对象

在该对象中进行的一切操作都是全局有效的。

示例:我要在所有的请求开始前,进行一些初始化操作,就可以这样直接使用 app 对象来定义

@app.before_request
def before_request():
    pass

完整的代码是:

from flask import Flask

app = Flask(__name__)


@app.before_request
def before_request():
    pass


if __name__ == '__main__':
    app.run()

二、创建应用

根据官方文档的说明,大型应用的目录结构是:

/yourapplication
    /runserver.py
    /yourapplication
        /__init__.py
        /views.py
        /static
            /style.css
        /templates
            layout.html
            index.html
            login.html
            ...

所以,要在项目的根目录下,创建一个应用的目录,这里则创建一个 demo 的应用,同时,将根目录下的 static 和 templates 文件夹删除。

在 demo 目录下,创建 3 个文件,分别是:“__init__.py”,“config.py”,“requirements.txt”。

__init__.py 这个就不多说了。

config.py 这个是 Flask 的配置信息。

requirements.txt 这个是用于方便 python 导入库使用的。

requirements.txt 文件里加上以下,这些都是要使用到的库。

Flask
Flask-SQLAlchemy
Flask-Login
Flask-WTF
pygments
PyMySQL

 三、封装 SQLAlchemy 库

1.在 config.py 文件增加以下配置

DEBUG = True
SQLALCHEMY_ECHO = False
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost/test?charset=utf8'
SECRET_KEY = '*\xff\x93\xc8w\x13\x0e@3\xd6\x82\x0f\x84\x18\xe7\xd9\\|\x04e\xb9(\xfd\xc3'

配置参数查看这里

 

2.在 demo 目录下创建一个 common 目录,做为公共库,在该目录下创建 data.py 文件

使用 fetchall() 是取得 SQL 脚本的返回结果,rowcount 才是取得影响行数。

# config=utf-8
from sqlalchemy import create_engine
from sqlalchemy.sql import text
from demo.config import SQLALCHEMY_DATABASE_URI, SQLALCHEMY_ECHO


def db_query(sql, settings=None, echo=None, args=None):
    """
    执行增删改 SQL 语句
    Args:
        sql: SQL 语句
        settings: 数据库连接字符串
        echo: 是否输出 SQL 语句
        args: SQL 参数

    Returns:
        执行结果
    """
    if settings is None:
        settings = SQLALCHEMY_DATABASE_URI

    if echo is None:
        echo = SQLALCHEMY_ECHO

    return create_engine(settings, echo=echo).connect().execute(text(sql), args).fetchall()


def db_execute(sql, settings=None, echo=None, args=None):
    """
    执行增删改 SQL 语句
    Args:
        sql: SQL 语句
        settings: 数据库连接字符串
        echo: 是否输出 SQL 语句
        args: SQL 参数

    Returns:
        影响行数
    """
    if settings is None:
        settings = SQLALCHEMY_DATABASE_URI

    if echo is None:
        echo = SQLALCHEMY_ECHO

    return create_engine(settings, echo=echo).connect().execute(text(sql), args).rowcount


# 测试代码
# SELECT * FROM py_user
# INSERT INTO py_user(name) VALUES('123456')
# data = db_query("SELECT * FROM py_user")
# print(data)

# data = db_execute("INSERT INTO py_user(name) VALUES(:name)", args={'name': '123456'})
# print(data)

 

3. 在 common 目录下创建一个 __init__.py 文件

__init__.py:

# config=utf-8
from flask_sqlalchemy import SQLAlchemy

__all__ = ['db']
db = SQLAlchemy()

这代码用于注册这个数据访问库。

 四、初始化应用

对 app 要进行数据库注册,还有传入配置信息等,要注意的是,这里需要另开一个文件来做这些事,不可以全写在 run.py 文件里,因为以后会在使用其它库的时候,在这里进行注册,但在真实使用时就要调用这里生成的对象,这个时候两个文件相互 import 就会出现异常。

所以,这里将 run.py 中创建 app 对象的功能提取到 demo 目录下的 __init__.py 文件里。

/demo/__init__.py

# config=utf-8
from flask import Flask
from demo.common import db


def create_app(config_filename=None):
    app = Flask(__name__)

    if config_filename is not None:
        # 注册数据访问信息
        app.config.from_pyfile(config_filename)

        # 初始化数据库
        configure_database(app)

    return app


def configure_database(app):
    """初始化数据库连接。
    Args:
        app:应用对象。
    Returns:
        该函数没有返回值。
    """
    db.init_app(app)

/run.py 文件里的代码则修改成

# config=utf-8
from flask import g
from flask_login import current_user
from demo import create_app

app = create_app('config.py')


@app.before_request
def before_request():
    """
    这里是全局的方法,在请求开始之前调用。
    其中 flask 有个全局的变量 g,它是和 session 一样的用途,可以使用它来保存当前用户的数据
    Returns:

    """
    g.user = current_user
    pass


if __name__ == '__main__':
    app.run()

 

posted @ 2016-02-23 09:47  cjnmy36723  阅读(2015)  评论(0编辑  收藏  举报