flask框架的使用

一、路由

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

from flask import Flask

app = Flask(__name__)


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


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



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


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

二、常用的HTTP方法

三、构造URL函数

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

from flask import Flask, url_for

app = Flask(__name__)


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


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


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


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

四、MVC设计模型

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

五、渲染模板

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

template中user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</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/<user>')
def show_user2(user):
    return render_template('user.html', name=user)  


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

六、模板变量

template中index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</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()

七、模板过滤器

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

template中index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</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'<h3>我的名字是{self.name},年龄{self.name}<h3>'


@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()

八、模板控制结构

template中index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</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'<h3>我的名字是{self.name},年龄{self.name}<h3>'


@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()

九、模板的继承

子模板中:
{% 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 %}

十、Web表单

注意:

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

template中login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
</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实现表单验证

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>login</title>
</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>

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

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

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

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>login</title>
</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语句

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"<User> 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()

十四、数据表关系

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"<User> 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"<Article> 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操作数据库 — 增删改查

增:

@app.route('/')
def hello_world():  
    # 1. 添加数据
    user = User(username='Silva72', email='737272215@qq.com', password='123456')
    db.session.add(user)
    db.session.commit()
    
    return 'Hello World!'

查:

@app.route('/')
def hello_world():  
    # 1. 添加数据
    # user = User(username='Silva72', email='737272215@qq.com', 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='737272215@qq.com', 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='737272215@qq.com', 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()不能修改,需要用数据迁移
数据迁移目的:不破坏原来数据,更改数据表的结构

模块情况
wtformsForm
flask_wtfFlaskFormflask对wtforms做出精简,更适合flask框架
flask_sqlalchemySQLAlchemy数据库相关的
flask_migrateAlembic
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"<User> 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"<Article> is {self.title}"

db.create_all()

if __name__ == '__main__':
    app.run()
Step 1:导包
Step 2:初始化一个迁移文件夹
flask db init
Step 3:当前的模型添加到迁移文件中
flask db migrate

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

Step 4:把迁移文件中对应的数据库操作,真正的映射到数据库中
flask db upgrade
Step 5:后期改动模型后,只需反复执行step3和4即可

十七、skill

点击按钮可以激发链接

不用js绑定按钮,用button套a标签
<button><a href="{{ url_for('front.logout') }}">按钮上的字</a></button>

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

555K77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值