flask框架的使用

文章目录

    • 一、路由
    • 二、常用的HTTP方法
    • 三、构造URL函数
    • 四、MVC设计模型
    • 五、渲染模板
    • 六、模板变量
    • 七、模板过滤器
    • 八、模板控制结构
    • 九、模板的继承
    • 十、Web表单
    • 十一、WTForms实现表单验证
    • 十二、防止CSRF攻击 和 flask_wtf的简化
    • 十三、flask_sqlalchemy 利用ORM创建数据表
    • 十四、数据表关系
    • 十五、Flask_SQLAlchemy操作数据库 --- 增删改查
      • 增:
      • 查:
      • 改:
      • 删:
    • 十六、Flask_Migrate实现数据迁移
        • Step 1:导包
        • Step 2:初始化一个迁移文件夹
        • Step 3:当前的模型添加到迁移文件中
        • Step 4:把迁移文件中对应的数据库操作,真正的映射到数据库中
        • Step 5:后期改动模型后,只需反复执行step3和4即可
    • 十七、skill
        • 点击按钮可以激发链接

flask框架的使用_第1张图片

一、路由

flask框架的使用_第2张图片

路由:处理URL和视图函数的这种关系,访问index则执行index视图函数。

flask框架的使用_第3张图片
from flask import Flask

app = Flask(__name__)


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


# 可变,动态
@app.route('/user/')
def show_user(username):
    return f'我是{username}'



@app.route('/post/')
def show_post_indo(post_id):
    return f'post_id是{post_id}'


if __name__ == '__main__':
    app.run()
flask框架的使用_第4张图片

二、常用的HTTP方法

flask框架的使用_第5张图片
flask框架的使用_第6张图片

三、构造URL函数

生成URL
url_for(函数名,参数赋值)

from flask import Flask, url_for

app = Flask(__name__)


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


@app.route('/user/')
def show_user(username):
    return f'我是{username}'


@app.route('/test/')
def test():
    return url_for('show_user', username='Andy')  # (函数名,参数赋值)


if __name__ == '__main__':
    app.run()
flask框架的使用_第7张图片

四、MVC设计模型

controller是调度中心,每一个表就是一个model。例如,订单表就是订单模型,view是视图层,里面存有多个模板。

flask框架的使用_第8张图片

五、渲染模板

render_template(模板名称,函数赋值)

template中user.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <h1>SpaceX课堂h1>
    <p>欢迎来到SpaceX课堂,我是{{ name }}p>
body>
html>

app.py

from flask import Flask, url_for, render_template

app = Flask(__name__)


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


# 静态
@app.route('/user1/')
def show_user1():
    return render_template('user.html', name='Max')


# 动态
@app.route('/user2/')
def show_user2(user):
    return render_template('user.html', name=user)  


if __name__ == '__main__':
    app.run()
flask框架的使用_第9张图片
flask框架的使用_第10张图片

六、模板变量

flask框架的使用_第11张图片

template中index.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>欢迎来到SpaceX课堂,我是{{ dict_val['name'] }},年龄{{ dict_val['age'] }}p>
    <ul>
        <li>
            {{ list_val[0] }}
        li>
        <li>
            {{ list_val[1] }}
        li>
        <li>
            {{ list_val[2] }}
        li>
    ul>
    <p>
        {{ user.name }}
        {{ user.get_info() }}
    p>
body>
html>

app.py

from flask import Flask, url_for, render_template

app = Flask(__name__)
app.debug = True


class User():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_info(self):
        return f'我的名字是{self.name},年龄{self.name}'


@app.route('/')
def index():
    dict_val = {'name': 'andy', 'age': 18}
    list_val = [i for i in range(10)]
    user = User('andy', 18)
    return render_template('index.html', dict_val=dict_val, list_val=list_val, user=user)  


if __name__ == '__main__':
    app.run()
flask框架的使用_第12张图片

七、模板过滤器

flask框架的使用_第13张图片

capitalize, safe, striptags的使用:
flask为了安全会把所有标签视为字符串,除非用过滤器safe确定其安全,才不转义为字符串。

template中index.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>欢迎来到SpaceX课堂,我是{{ dict_val['name']|capitalize }},年龄{{ dict_val['age'] }}p>
    <ul>
        <li>
            {{ list_val[0] }}
        li>
        <li>
            {{ list_val[1] }}
        li>
        <li>
            {{ list_val[2] }}
        li>
    ul>
    <p>
        {{ user.get_info()|striptags}}
    p>
    <p>
        {{ user.name }}
        {{ user.get_info()|safe}}
    p>
body>
html>

app.py

from flask import Flask, url_for, render_template

app = Flask(__name__)
app.debug = True


class User():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_info(self):
        return f'

我的名字是{self.name},年龄{self.name}

' @app.route('/') def index(): dict_val = {'name': 'andy', 'age': 18} list_val = [i for i in range(10)] user = User('andy', 18) return render_template('index.html', dict_val=dict_val, list_val=list_val, user=user) # 参数模板名称 if __name__ == '__main__': app.run()

flask框架的使用_第14张图片

八、模板控制结构

flask框架的使用_第15张图片

template中index.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>欢迎来到SpaceX课堂,我是{{ dict_val['name']|capitalize }},年龄{{ dict_val['age'] }}p>
    <ul>
        {% for item in list_val %}
        <li>
            {{ item }}
            {% for i in range(2) %}
                测试
            {% endfor %}
        li>
        {% endfor %}
    ul>
    <p>
        {% if user.name == 'andy' %}
            欢迎管理员登录
        {% elif user.name == 'daxiong' %}
            欢迎版主登录
        {% else %}
            欢迎{{ user.name }}登录
        {% endif %}
    p>
body>
html>

app.py

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True


class User():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_info(self):
        return f'

我的名字是{self.name},年龄{self.name}

' @app.route('/') def index(): dict_val = {'name': 'andy', 'age': 18} list_val = [i for i in range(10)] user = User('andy', 18) return render_template('index.html', dict_val=dict_val, list_val=list_val, user=user) # 参数模板名称 if __name__ == '__main__': app.run()

flask框架的使用_第16张图片

九、模板的继承

子模板中:
{% extends ‘base.html’ %}
{% block title %} 填空… {% endblock %}
{% block body %} 填空… {% endblock %}

template中base.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}父模板{% endblock %}title>
head>
<body>

{% block nav %}
首页|商品分类|关于我们|联系我们
{% endblock %}


{% block body %}
{% endblock %}


{% block footer %}
    购物流程
    会员介绍
    生活旅行/团购
    常见问题
    大家电
    联系客服
{% endblock %}

body>
html>

template中index.html

{% extends 'base.html' %}

{% block title %}子模板{% endblock %}

{% block body %}
    <p>欢迎来到SpaceX课堂,我是{{ dict_val['name']|capitalize }},年龄{{ dict_val['age'] }}p>
    <ul>
        {% for item in list_val %}
        <li>
            {{ item }}
            {% for i in range(2) %}
                测试
            {% endfor %}
        li>
        {% endfor %}
    ul>
    <p>
        {% if user.name == 'andy' %}
            欢迎管理员登录
        {% elif user.name == 'daxiong' %}
            欢迎版主登录
        {% else %}
            欢迎{{ user.name }}登录
        {% endif %}
    p>
{% endblock %}
flask框架的使用_第17张图片

十、Web表单

注意:

  1. action表示提交到哪里
  2. 注册method不用get,因为会传到URL中,不安全
  3. 不会用到js,只用form.py和views.py视图函数
  4. submit按钮可整表提交,不需绑定按钮
flask框架的使用_第18张图片

template中login.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>logintitle>
head>

<body>
<form action="" method="post">
    <div>
        <label>用户名label>
        <input type="text" name="username" value="">
    div>
    <div>
        <label>密码label>
        <input type="password" name="password" value="">
    div>
    <button>提交button>
form>
body>
html>

app.py

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True


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


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

十一、WTForms实现表单验证

flask框架的使用_第19张图片
flask框架的使用_第20张图片
flask框架的使用_第21张图片

forms - app - html 三件套

forms.py

from wtforms import Form, StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length


class LoginForm(Form):
    username = StringField(label='用户名', validators=[
        DataRequired('请填写用户名'),
        Length(min=6, max=50, message='用户名长度在6-50个字符之间')
    ])
    password = PasswordField(label='密码', validators=[
        DataRequired('请填写密码'),
        Length(min=6, max=50, message='密码在6-50')
    ])
    submit = SubmitField(label='提交')

app.py

from flask import Flask, render_template, request
from forms import LoginForm

app = Flask(__name__)
app.debug = True


@app.route('/', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)  # request.form是用户提交的表单内容
    if request.method == 'POST' and form.validate():
        pass
    return render_template('login.html', form=form)


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

templates中login.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>logintitle>
head>

<body>
<form action="" method="post">
    <div>
        {{ form.username.label }}
        {{ form.username }}
        {% for error in form.username.errors %}
            {{ error }}
        {% endfor %}
    div>
    <div>
        {{ form.password.label }}
        {{ form.password }}
        {% for error in form.password.errors %}
            {{ error }}
        {% endfor %}
    div>
    {{ form.submit }}
form>
body>
html>
flask框架的使用_第22张图片

十二、防止CSRF攻击 和 flask_wtf的简化

【注意】!!!!!的位置是基于十一章改变/多加的

  1. 防止CSRF攻击:每次访问一个服务器,给用户发token,提交表单时,也提交token。假的网站不能高仿token,所以利用token可以防止CSRF攻击。
flask框架的使用_第23张图片
  1. flask_wtf的简化
模块 情况
wtforms Form
flask_wtf FlaskForm flask对wtforms做出精简,更适合flask框架
flask_sqlalchemy SQLAlchemy 数据库相关的

forms - app - html 三件套

forms.py

from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length
from flask_wtf import FlaskForm  # 简化!!!!!


class LoginForm(FlaskForm):  # 简化!!!!!
    username = StringField(label='用户名', validators=[
        DataRequired('请填写用户名'),
        Length(min=6, max=50, message='用户名长度在6-50个字符之间')
    ])
    password = PasswordField(label='密码', validators=[
        DataRequired('请填写密码'),
        Length(min=6, max=50, message='密码在6-50')
    ])
    submit = SubmitField(label='提交')

app.py

from flask import Flask, render_template, request
from forms import LoginForm

app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'spaceX'


@app.route('/', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)  # request.form是用户提交的表单内容
    # if request.method == 'POST' and form.validate():
    if form.validate_on_submit():  # 简化!!!!!!
        pass
    return render_template('login.html', form=form)


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

templates中login.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>logintitle>
head>

<body>
<form action="" method="post">
    {{ form.csrf_token }}  # token !!!!!!
    <div>
        {{ form.username.label }}
        {{ form.username }}
        {% for error in form.username.errors %}
            {{ error }}
        {% endfor %}
    div>
    <div>
        {{ form.password.label }}
        {{ form.password }}
        {% for error in form.password.errors %}
            {{ error }}
        {% endfor %}
    div>
    {{ form.submit }}
form>
body>
html>

十三、flask_sqlalchemy 利用ORM创建数据表

ORM: 将数据库转化为python对象,不用再记忆SQL语句

flask框架的使用_第24张图片
flask框架的使用_第25张图片
flask框架的使用_第26张图片
flask框架的使用_第27张图片
flask框架的使用_第28张图片
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import pymysql


app = Flask(__name__)
app.debug = True

# 1. 配置app参数
app.config['SECRET_KEY'] = 'spaceX'
app.config['SQLALCHEMY_DATABASE_URI'] = (
    'mysql+pymysql://用户名:密码@localhost/flask_demo?charset=utf8mb4'
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True


# 2. 定义数据库
db = SQLAlchemy(app)


# 3. 定义数据库表的ORM类
class User(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(20), nullable=False)

    def __repr__(self):
        return f" is {self.username}"


# 4. 创建数据库中的所有表 
db.create_all()


@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'


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

十四、数据表关系

flask框架的使用_第29张图片
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import pymysql


app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'spaceX'
app.config['SQLALCHEMY_DATABASE_URI'] = (
    'mysql+pymysql://root:Root8834@localhost/flask_demo?charset=utf8mb4'
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(20), nullable=False)
    articles = db.relationship('Article', backref='user')  # 关联

    def __repr__(self):
        return f" is {self.username}"


class Article(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    title = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 定义外键

    def __repr__(self):
        return f"
is {self.title}" db.create_all() @app.route('/') def hello_world(): # put application's code here return 'Hello World!' if __name__ == '__main__': app.run()

十五、Flask_SQLAlchemy操作数据库 — 增删改查

flask框架的使用_第30张图片

增:

flask框架的使用_第31张图片
@app.route('/')
def hello_world():  
    # 1. 添加数据
    user = User(username='Silva72', email='[email protected]', password='123456')
    db.session.add(user)
    db.session.commit()
    
    return 'Hello World!'

查:

flask框架的使用_第32张图片
flask框架的使用_第33张图片
@app.route('/')
def hello_world():  
    # 1. 添加数据
    # user = User(username='Silva72', email='[email protected]', password='123456')
    # db.session.add(user)
    # db.session.commit()

    # 2. 查找数据
    users = User.query.all()
    for user in users:
        print(user.id)
        print(user.username)
    print(User.query.get(2))
    print(User.query.count())
    print(User.query.filter_by(id=1)[0].email)
    print(User.query.get_or_404(2))

    return 'Hello World!'

改:

@app.route('/')
def hello_world():  # put application's code here
    # 1. 添加数据
    # user = User(username='Silva72', email='[email protected]', password='123456')
    # db.session.add(user)
    # db.session.commit()

    # 2. 查找数据
    # users = User.query.all()
    # for user in users:
    #     print(user.id)
    #     print(user.username)
    # print(User.query.get(2))
    # print(User.query.count())
    # print(User.query.filter_by(id=1)[0].email)
    # print(User.query.get_or_404(2))

    # 3. 修改数据
    user = User.query.filter_by(id=1)[0]
    user.username = "新名字"
    db.session.commit()
    
    return 'Hello World!'

删:

@app.route('/')
def hello_world():  # put application's code here
    # 1. 添加数据
    # user = User(username='Silva72', email='[email protected]', password='123456')
    # db.session.add(user)
    # db.session.commit()

    # 2. 查找数据
    # users = User.query.all()
    # for user in users:
    #     print(user.id)
    #     print(user.username)
    # print(User.query.get(2))
    # print(User.query.count())
    # print(User.query.filter_by(id=1)[0].email)
    # print(User.query.get_or_404(2))

    # 3. 修改数据
    # user = User.query.filter_by(id=1)[0]
    # user.username = "新名字"
    # db.session.commit()

    # 4. 删除数据
    user = User.query.filter_by(id=1)[0]
    db.session.delete(user)
    db.session.commit()

    return 'Hello World!'

十六、Flask_Migrate实现数据迁移

修改表类的结构后,db.create_all()不能修改,需要用数据迁移
数据迁移目的:不破坏原来数据,更改数据表的结构

flask框架的使用_第34张图片
模块 情况
wtforms Form
flask_wtf FlaskForm flask对wtforms做出精简,更适合flask框架
flask_sqlalchemy SQLAlchemy 数据库相关的
flask_migrate Alembic
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import pymysql
from flask_migrate import Migrate


app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'spaceX'
app.config['SQLALCHEMY_DATABASE_URI'] = (
    'mysql+pymysql://root:Root8834@localhost/flask_demo?charset=utf8mb4'
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)

# 绑定app和数据库
migrate = Migrate(app, db)


class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    gender = db.Column(db.Boolean, default=True)
    hobby = db.Column(db.String(120))
    password = db.Column(db.String(20), nullable=False)
    articles = db.relationship('Article', backref='user')  # 关联

    def __repr__(self):
        return f" is {self.username}"


class Article(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    title = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 定义外键

    def __repr__(self):
        return f"
is {self.title}" db.create_all() if __name__ == '__main__': app.run()

Step 1:导包

flask框架的使用_第35张图片

Step 2:初始化一个迁移文件夹

flask db init
flask框架的使用_第36张图片

Step 3:当前的模型添加到迁移文件中

flask db migrate

e.g. flask db migrate -m "add password to user"

flask框架的使用_第37张图片

Step 4:把迁移文件中对应的数据库操作,真正的映射到数据库中

flask db upgrade
flask框架的使用_第38张图片

Step 5:后期改动模型后,只需反复执行step3和4即可

十七、skill

点击按钮可以激发链接

不用js绑定按钮,用button套a标签

你可能感兴趣的:(Flask,flask,python,后端)