使用 Flask 框架写用户登陆功能的Demo时碰到的各类坑(一)——建立应用css
使用 Flask 框架写用户登陆功能的Demo时碰到的各类坑(二)——使用蓝图功能进行模块化html
使用 Flask 框架写用户登陆功能的Demo时碰到的各类坑(三)——使用Flask-Login库实现登陆功能python
使用 Flask 框架写用户登陆功能的Demo时碰到的各类坑(四)——对 run.py 的调整mysql
使用 Flask 框架写用户登陆功能的Demo时碰到的各类坑(五)——实现注册功能sql
Flask 中文文档数据库
Flask_Login 文档flask
Flask-sqlalchemy 文档session
Jinja2 模板文档app
为了熟悉 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
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()
这代码用于注册这个数据访问库。
4、初始化应用
对 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()