一步一步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.