一步一步FLASK(一)

簡介:

本文是記錄本人創建一個flask項目的完整過程。css

涉及FLASK的諸多實用技術。html

一:基本FLASK

pycharm創建FLASK項目便可運行。前端

代碼以下:python

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'hello'


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

 

直接運行便可。pycharm的默認訪問地址是http://127.0.0.1:5000/mysql

修改默認的app.py爲main.py,即主入口文件redis

二:引入bootstrap

前端想少寫東西,就要有前端框架,bootstrap是一個流行的框架,原有的flask-bootstrap中止更新了,改用一個繼承者Bootstrap-Flasksql

1.手動安裝擴展Bootstrap-Flask

pip install Bootstrap-Flask

 

2.建立html模板

在templates目錄下建立目錄base,在base目錄下建立base.html數據庫

<!doctype html>
<html lang="en">
  <head>
    {% block head %}
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    {% block styles %}
    <!-- Bootstrap CSS -->
    {{ bootstrap.load_css() }}
    {% endblock %}

    <title>Your page title</title>
    {% endblock %}
  </head>
  <body>
    <!-- Your page content -->
    {% block content %}{% endblock %}

    {% block scripts %}
    <!-- Optional JavaScript -->
    {{ bootstrap.load_js() }}
    {% endblock %}
  </body>
</html>
View Code

 

這個代碼是bootstrap-flask推薦的。npm

3.修改app.py

from flask_bootstrap import Bootstrap
from flask import Flask, render_template #添加渲染模板的庫

app = Flask(__name__)

bootstrap = Bootstrap(app)

@app.route('/')
def hello_world():
    return render_template('base/base.html')   #修改返回爲渲染模板


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

 

運行訪問,雖然是個空頁面,可是查看源碼,會看到多了加載CSS和JSflask

4.可選(配置本地加載CSS和JS)

from flask_bootstrap import Bootstrap
from flask import Flask, render_template

app = Flask(__name__)

bootstrap = Bootstrap(app)
app.config['BOOTSTRAP_SERVE_LOCAL'] = True  #配置flask-bootstrap加載本地數據


@app.route('/')
def hello_world():
    return render_template('base/base.html')


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

由原來的cdn加速地址改成本地了。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" type="text/css">

<link rel="stylesheet" href="/bootstrap/static/css/bootstrap.min.css" type="text/css">

 

三:建立requirements.txt

1.爲了項目複製以及部署,須要對第三方庫進行管理。

在項目根目錄建立文件make_requirement.py

import os, sys, platform

# 找到當前目錄
project_root = os.path.dirname(os.path.realpath(__file__))
print(project_root)

#不一樣的系統,使用不一樣的命令語句

if platform.system() == 'Linux':
    command = sys.executable + ' -m pip freeze > ' + project_root + '/requirements.txt'
if platform.system() == 'Windows':
    command = '"' + sys.exec_prefix + '\Scripts\pip" freeze > ' + project_root + '\\requirements.txt'

# # 拼接生成requirements命令
print(command)
#
# # 執行命令。
os.system(command)
View Code

 

運行後便可在項目根目錄生成requirements.txt

四:加入藍圖Blueprint

1.根據藍圖結構建立目錄和文件

 以下:

D:.
│  main.py
│  make_requirement.py
│  requirements.txt
│
├─app
│  └─users
│          view.py    #新建視圖文件
│
├─static
├─templates
│  └─base
│          base.html
│
└─__pycache__
        main.cpython-37.pyc
View Code

 

2.編輯視圖文件

編輯/app/users/view.py

from flask import Blueprint

user = Blueprint('user', __name__)


@user.route('/')
def show():
    return 'user.default'


@user.route('/register')
def register():
    return 'user.register'


@user.route('/login')
def login():
    return 'user.login'


@user.route('/logout')
def logout():
    return 'user.logout'
View Code

 

 

3.註冊藍圖到主入口

編輯main.py

 

from flask_bootstrap import Bootstrap
from flask import Flask, render_template
from app.users.view import user   #引入視圖

app = Flask(__name__)

bootstrap = Bootstrap(app)
app.config['BOOTSTRAP_SERVE_LOCAL'] = True

app.register_blueprint(user, url_prefix='/user') #註冊視圖

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

 

4.測試訪問

http://127.0.0.1:5000/user/

http://127.0.0.1:5000/user/register

http://127.0.0.1:5000/user/login

http://127.0.0.1:5000/user/logout

均可以訪問

五:引入數據庫sqlalchemy alembic MySQL-connector-python

1.手動安裝擴展

pip install sqlalchemy alembic MySQL-connector-python

2.建立配置文件

建立config.py

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('mysql+mysqlconnector://zzcld:zzcld@mariadb/zzcld', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
View Code

 

3.修改flask默認配置方法

把main.py中定義的配置,放進config.py

修改config.py

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base


class Config(object):    #配置這項
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'mysql+mysqlconnector://zzcld:zzcld@mariadb/zzcld'
    BOOTSTRAP_SERVE_LOCAL = True


engine = create_engine(Config.DATABASE_URI, convert_unicode=True)    #修改數據庫路徑
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
View Code

4.使用alembic

http://www.javashuo.com/article/p-kprqthiu-da.html

 

5.建立用戶model

建立/app/users/model.py

from config import Base
from sqlalchemy import Column, Integer, String, Boolean


class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(50))  #用戶名
    password = Column(String(120)) #密碼
    activity = Column(Boolean)         #是否活動/禁用
View Code

 

6.配置alembic

須要修改配置的有兩個文件。

alembic.ini,其中配置數據庫鏈接參數。

修改這行:

sqlalchemy.url = driver://user:pass@localhost/dbname

改成咱們的數據鏈接參數:

sqlalchemy.url = mysql+mysqlconnector://zzcld:zzcld@mariadb/zzcld

env.py,其中配置models。

修改這行:

target_metadata = None

修改成:

import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
from app.users import model
target_metadata = model.Base.metadata
View Code

7.使用alembic,更新數據庫

alembic revision --autogenerate       生成alembic升級腳本

alembic upgrade head                     升級數據庫結構到最新版

執行這兩個命令,或用擴展工具的圖形菜單。

8.檢查數據庫

使用第三方工具,鏈接你的數據庫查看數據庫創建狀況。

 

六:引入表單,處理註冊登陸Flask-wtf

這個是一個表單庫,基於wtform。處理各類表單,先處理註冊和登陸。

1.安裝第三方庫flask-wtf

pip install  flask-wtf

2.建立表單

修改user/register,既/app/users/view.py

class register_form(FlaskForm):   #註冊表單
    username = StringField('用戶名', validators=[DataRequired()])
    password = StringField('密碼', validators=[DataRequired()])


class login_form(FlaskForm):    #登陸表單
    username = StringField('用戶名', validators=[DataRequired()])
    password = StringField('密碼', validators=[DataRequired()])
View Code

3.建立模板

建立/templates/users/register.html

建立/templates/users/login.html

內容同樣

{% extends 'base/base.html' %}
{% block content %}
<form method="POST" action="#">
    {{ form.csrf_token }}
    {{ form.username.label }} {{ form.username(size=20) }}
    <br>
    {{ form.password.label }} {{ form.password(size=20) }}
    <br>
    <input type="submit" value="提交">
</form>

{% endblock %}
View Code

4.渲染表單

修改/app/users/view.py

@user.route('/register', methods=('GET', 'POST'))
def register():
    form = register_form()  # 初始化表單
    return render_template('users/register.html', form=form)

@user.route('/login', methods=('GET', 'POST'))
def login():
    form = login_form()  # 初始化表單
    return render_template('users/login.html', form=form)
View Code

5.嘗試訪問

http://127.0.0.1:5000/user/register

http://127.0.0.1:5000/user/login

已經有了一個表單,有用戶名和密碼兩個框,一個提交按鈕。

6.處理業務邏輯

修改/app/users/view.py

@user.route('/register', methods=('GET', 'POST'))
def register():
    form = register_form()  # 初始化表單
    if form.validate_on_submit():  # 若是頁面有提交數據,在此建立數據庫條目
        new_user = Users(username=form.username.data, password=form.password.data, activity=True)
        db_session.add(new_user)
        db_session.commit()
        db_session.close()
        return redirect(url_for('user.login'))  # 跳轉到登陸頁面
    return render_template('users/register.html', form=form)


@user.route('/login', methods=('GET', 'POST'))
def login():
    form = login_form()  # 初始化表單
    if form.validate_on_submit():  # 若是頁面有提交數據,在此建立數據庫條目
        login_user = db_session.query(Users).filter_by(username=form.username.data).first() # 查找name=jack的
        print(login_user.username)
        print(form.password.data)
        if login_user.password==form.password.data:
            return redirect(url_for('user.show'))  #
        else:
            return '登陸失敗'
    return render_template('users/login.html', form=form)
View Code

7.嘗試註冊和登陸

我測試正常

七:登陸後的驗證flask-session

爲防止cookie僞造,我使用session來保存用戶信息。

1.手動安裝第三方庫

pip install flask-session

2.配置並注入flask-session

修改main.py

from flask_bootstrap import Bootstrap
from flask import Flask, render_template
from app.users.view import user  # 引入視圖
from config import Config
from flask_session import Session

app = Flask(__name__)
app.config.from_object(Config)       #不知道爲何,注入Session以前要先加載配置   
Session(app)                         #新加
bootstrap = Bootstrap(app)
app.register_blueprint(user, url_prefix='/user')  


@app.route('/')
def default():
    return render_template('base/base.html')


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

修改config.py

class Config(object):  # 配置這項
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'mysql+mysqlconnector://zzcld:zzcld@mariadb/zzcld'
    BOOTSTRAP_SERVE_LOCAL = True
    SECRET_KEY = os.urandom(24)  # 加密的密碼,部署時修改,測試時使用隨機字符串
    SESSION_TYPE = 'filesystem'  # session存儲類型,暫時使用文件存儲,部署時會改用redis
    SESSION_PERMANENT = False  # 是否永久生效,false就是關閉瀏覽器失效
    SESSION_USE_SIGNER = True   #是否簽名會話cookie sid 避免僞造,簽名
    SESSION_FILE_THRESHOLD = 2  #保存session條數,既最大同時登陸人數,默認500,部署時修改
View Code

3.處理業務邏輯

登陸時,設置session,登出時,清空session,用戶默認頁,讀取session。

修改/app/users/view.py

@user.route('/')
def show():
    return (session.get('key', 'not set')+'設置'+session.get('user', 'not set'))

@user.route('/login', methods=('GET', 'POST'))
def login():
    form = login_form()  # 初始化表單
    if form.validate_on_submit():  # 若是頁面有提交數據,在此建立數據庫條目
        login_user = db_session.query(Users).filter_by(username=form.username.data).first() # 查找name=jack的
        print(login_user.username)
        print(form.password.data)
        if login_user.password==form.password.data:
            session['key'] = 'value'
            session['user'] = 'user'
            return redirect(url_for('user.show'))  #
        else:
            return '登陸失敗'
    return render_template('users/login.html', form=form)


@user.route('/logout')
def logout():
    session.clear()
    return 'user.logout'
View Code

4.訪問測試

http://127.0.0.1:5000/user/      登陸前和登陸後,顯示的不同。

http://127.0.0.1:5000/user/login

http://127.0.0.1:5000/user/logout

八:釋放數據庫鏈接

我是常常網機釋放數據庫鏈接,這不是一個好習慣,好在flask有內置的裝飾器能夠在在請求結束時或在應用程序關閉時自動刪除數據庫會話:

1.編輯main.py

from flask_bootstrap import Bootstrap
from flask import Flask, render_template
from app.users.view import user
from config import Config
from config import db_session    #引入session
from flask_session import Session

app = Flask(__name__)
app.config.from_object(Config)
Session(app)
bootstrap = Bootstrap(app)
app.register_blueprint(user, url_prefix='/user')


@app.teardown_appcontext                 #新加
def shutdown_session(exception=None):
    db_session.remove()


@app.route('/')
def default():
    return render_template('base/base.html')


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

九:

1.

2.

3.

4.

5.

6.

7.

8.

9.

十:

1.

2.

3.

4.

5.

6.

7.

8.

9.

相關文章
相關標籤/搜索