flask框架3
文章目录
一. 模板
1. 控制代码块 (重点)
{% for item in my_list if item.id != 5 %}
{% if loop.index == 1 %}
<li style="background-color: blue">{{ item.value }}</li>
{% elif loop.index == 2 %}
<li style="background-color: cadetblue">{{ item.value }}</li>
{% elif loop.index == 3 %}
<li style="background-color: coral">{{ item.value }}</li>
{% else %}
<li style="background-color: pink">{{ item.value }}</li>
{% endif %}
{% endfor %}
2. 前端渲染 vs 后端渲染 (理解)
- 后端渲染: 在服务端使用正则表达式
直接
对html进行渲染- 缺点: 前后端不分离, 开发效率很低
- 优点: 有利于
SEO
(搜索引擎优化)
- 前端渲染: 使用
js
来修改html内容, 一般前端会发出ajax请求
, 后端获取数据后以json形式
返回- 优点:
- 前后端分离, 开发效率比较高
- 可以进行
局部动态刷新
- 优点:
3. 模板继承 (重点)
- 作用: 抽取重复的html代码, 减少代码冗余
- 基类文件
- 将相同的内容放入基类文件
- 在需要自定义的位置, 定义代码块, 以便子类文件进行重写
- 子类文件
- 继承基类文件
- 在需要自定义的位置, 重写代码块
4. 模板中可用的变量/函数
二. CSRF
1. CSRF攻击过程
- CSRF: 跨站请求伪造
- 攻击对象: 使用
状态保持
机制实现了免密码登录
的网站 - 攻击方式: 利用
隐藏表单
发起跨站请求
, 由于网站只使用账号验证并使用了状态保持, 所以会被攻击
2. CSRF保护 (理解)
- 保护办法:
生成
随机令牌,保存
到cookie和表单中- 发起转账请求时,
校验
cookie和表单中的令牌是否一致
3. Flask中的CSRF保护 (重点)
- flask组件
flask-wtf
中封装csrf保护机制 - 生成和派发令牌
- 校验令牌 开启CSRF保护
三. flask-SQLAlchemy
1. ORM
- ORM: 对象关系映射
- 作用: 可以让开发者用
原生代码
的方式来操作数据库
- 优点: 开发者不再需要关注SQL语句, 也不需要针对不同的数据库进行语法学习
- 缺点: 性能会有一定的消耗
- 作用: 可以让开发者用
2. 配置和连接
- 需要安装
flask-sqlalchemy
和flask-mysqldb
# 设置数据库的连接地址
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@127.0.0.1:3306/test20"
# 是否监听数据库变化 一般不打开, 比较消耗性能
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 会在控制台中显示底层执行的sql语句
app.config["SQLALCHEMY_ECHO"] = True
# 创建数据库操作对象(建立了数据库连接)
db = SQLAlchemy(app)
- 使用pymsyql连接数据库(如果使用flask-mysqldb连接数据库失败, 则使用该方式)
- 安装组件
pip install pymysql
- 连接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:mysql@127.0.0.1:3306/test20'
- 安装组件
3. 构建表
4. 增删改
5. 数据查询 (重点)
查询所有用户数据
User.query.all()
查询有多少个用户
User.query.count()
查询第1个用户
User.query.first()
User.query.get(1) # 根据id查询
查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter_by(id=4).all() # 简单查询 使用关键字实参的形式来设置字段名
User.query.filter(User.id == 4).all() # 复杂查询 使用恒等式等其他形式来设置条件
查询名字结尾字符为g的所有用户[开始 / 包含]
User.query.filter(User.name.endswith("g")).all()
User.query.filter(User.name.startswith("w")).all()
User.query.filter(User.name.contains("n")).all()
User.query.filter(User.name.like("%n%g")).all() 模糊查询
查询名字和邮箱都以li开头的所有用户[2种方式]
User.query.filter(User.name.startswith("li"), User.email.startswith("li")).all()
from sqlalchemy import and_
User.query.filter(and_(User.name.startswith("li"), User.email.startswith("li"))).all()
查询age是25 或者 `email`以`itheima.com`结尾的所有用户
from sqlalchemy import or_
User.query.filter(or_(User.age == 25, User.email.endswith("itheima.com"))).all()
查询名字不等于wang的所有用户[2种方式]
from sqlalchemy import not_
User.query.filter(not_(User.name == "wang")).all()
User.query.filter(User.name != "wang").all()
查询id为[1, 3, 5, 7, 9]的用户
User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all()
所有用户先按年龄从小到大, 再按id从大到小排序, 取前5个
User.query.order_by(User.age, User.id.desc()).limit(5).all()
分页查询, 每页3个, 查询第2页的数据
pn = User.query.paginate(2, 3)
pn.items 获取该页的数据 pn.page 获取当前的页码 pn.pages 获取总页数
6. 一对多关系 (重点)
-
多表关系需要
外键
来进行关联 -
一对多关系中, 外键在
多的一方
-
使用
关系属性
来关联和查询数据- 1> 仍需要定义外键 2> 定义关系属性 3> 使用关系属性/外键建立关联
- 1> 仍需要定义外键 2> 定义关系属性 3> 使用关系属性/外键建立关联
7. 图书案例 (重点)
1. 定义模型&添加测试数据
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 设置数据库的连接地址
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@127.0.0.1:3306/book20"
# 是否监听数据库变化 一般不打开, 比较消耗性能
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 创建数据库操作对象(建立了数据库连接)
db = SQLAlchemy(app)
# 作者表 一
class Author(db.Model):
__tablename__ = "authors"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(48), unique=True)
books = db.relationship("Book", backref="author") # 关系属性
# 书籍表 多
class Book(db.Model):
__tablename__ = "books"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(48), unique=True)
author_id = db.Column(db.Integer, db.ForeignKey("authors.id")) # 设置外键
@app.route('/')
def index():
return "index"
if __name__ == '__main__':
# 会删除所有继承db.Model的表
db.drop_all()
# 会创建所有继承自db.Model的表
db.create_all()
# 生成数据
au1 = Author(name='老王')
au2 = Author(name='老尹')
au3 = Author(name='老刘')
# 把数据提交给用户会话
db.session.add_all([au1, au2, au3])
# 提交会话
db.session.commit()
bk1 = Book(name='老王回忆录', author_id=au1.id)
bk2 = Book(name='我读书少,你别骗我', author_id=au1.id)
bk3 = Book(name='如何才能让自己更骚', author_id=au2.id)
bk4 = Book(name='怎样征服美丽少女', author_id=au3.id)
bk5 = Book(name='如何征服英俊少男', author_id=au3.id)
# 把数据提交给用户会话
db.session.add_all([bk1, bk2, bk3, bk4, bk5])
# 提交会话
db.session.commit()
app.run(debug=True)