使用 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()