一、路由
路由:处理URL和视图函数的这种关系,访问index则执行index视图函数。
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()
二、常用的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/')
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>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()
六、模板变量
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()
七、模板过滤器
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()
八、模板控制结构
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()
九、模板的继承
子模板中:
{% 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表单
注意:
- action表示提交到哪里
- 注册method不用get,因为会传到URL中,不安全
- 不会用到js,只用form.py和views.py视图函数
- submit按钮可整表提交,不需绑定按钮
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实现表单验证
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)
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>
十二、防止CSRF攻击 和 flask_wtf的简化
【注意📢】!!!!!的位置是基于十一章改变/多加的
包模块情况wtformsFormflask_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)
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语句
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://用户名:密码@localhost/flask_demo?charset=utf8mb4'
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
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}"
db.create_all()
@app.route('/')
def hello_world():
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" 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():
return 'Hello World!'
if __name__ == '__main__':
app.run()
十五、Flask_SQLAlchemy操作数据库 — 增删改查
@app.route('/')
def hello_world():
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():
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():
user = User.query.filter_by(id=1)[0]
user.username = "新名字"
db.session.commit()
return 'Hello World!'
@app.route('/')
def hello_world():
user = User.query.filter_by(id=1)[0]
db.session.delete(user)
db.session.commit()
return 'Hello World!'
十六、Flask_Migrate实现数据迁移
修改表类的结构后, db.create_all()
不能修改,需要用数据迁移
数据迁移目的:不破坏原来数据,更改数据表的结构
包模块情况wtformsFormflask_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)
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()
flask db init
flask db migrate
e.g. flask db migrate -m "add password to user"
flask db upgrade
十七、skill
不用js绑定按钮,用button套a标签
<button><a href="{{ url_for('front.logout') }}">按钮上的字</a></button>
Original: https://blog.csdn.net/SergioSilva/article/details/122857701
Author: Silva72
Title: flask框架的使用
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/745653/
转载文章受原作者版权保护。转载请注明原作者出处!