py01-python之flask笔记
一、前奏
from flask import Flask # 从flask包导入Flask类
app = Flask(__name__) # 使用Flask类创建一个app对象
"""
1、__name__:代表当前app.py这个模块
2、作用:出现bug快速定位,对于寻找模板文件有一个相对路径
"""
@app.route('/') # 创建一个路由和视图函数的映射,/是根路由
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
1、debug模式:app.run(debug=True)
(1)开启debug模式后,只要修改代码后保存,就会自动重新加载,不需要手动重启项日
(2)如果开发的时候,出现bug,如果开启了debug模式,在浏览器上就可以看到出错信息
2、修改host:让其他电脑能访问到我电脑上的fLask项目。修改port端口号:如果5000端口被其他程序占用了,那么可以通过修改port来监听新端口号
(1)app.run(debug=True, host="0.0.0.0", port="8000")
3、urL与视图:path与视图
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route("/profile")
def profile():
return '我是个人中心!'
@app.route("/blog/<int:blog_id>")
def blog_list(blog_id):
# 带参数的urL;将参数固定到了path中
return “您访间的博客是:%s” % blog_id
@app.route('/book/list')
def book_list():
# arguments:参数。request.args:类宇典类型
page = request.args.get("page",default=1,type=int) # 参数page,默认1。/book/list?page=2:获取第二页的数据
return f"您获取的是第{page}的图书列表!"
备注:除了int 类型以外,URL中的参数还可以指定以下类型
(1)string:字符串类型。可以接受除/以外的字符
(2)int:整形。可以接受能通过int()方法转换的字符
(3)float:浮点类型。可以接受能通过float()方法转换的字符
(4)path:路径。类似string,但是中间可以添加/
(5)uuid:UUID类型。UUID是由一组32位数的16进制所构成
(6)any:备选值中的任何一个
二、模板渲染(基于jinja2)
1、实际网站开发中,为了让网页更加美观,是需要渲染一个有富文本标签的页面,通常包含大量的HTML代码,如果把这些HTML代码用字符串的形式写在视图函数中,后期的代码维护将变得噩梦一般。
因此,在Flask中,渲染HTML通常会交给模板引擎来做,而Flask中默认配套的模板引擎是Jinja2,Jinja2的作者也是Flask的作者,Jinja2可以独立于Flask使用,比如被Django使用。Jinja2是一个高效、可扩展的模板引擎。
@app.route("/blog/<blog_id>")
def blog_detail(bloq_id):
return render_template("blog_detai.html",blog_id=blog_id,username="派森")
# render_template:接收HTML文件和传给HTML文件的变量
三、模板访问对象属性(基于jinja2)
from flask import Flask,render_template
app=Flask(__name__)
class User:
def __init__(self,username,email):
self.username = username
self.email= email
@app.route('/')
def hello_world():
user = User(username="派森",email="xx@qq.com")
person = {
"username":"张三",
"email": "zhangsan@qq.com"
}
return render_template("index.html",user=user,person=person)
## html中:
<div>{{ user.username }} / {{ user.email }}</div>
<div>{{ person['username'] }} / {{ person.username }}</div>
四、过滤器的使用(基于jinja2)
1、在Python 中,如果需要对某个量进行处理,我们可以通过函数来实现。在模板中,我们则是通过过滤器来实现的。过滤器本质上也是函数,但是在模板中使用的方式是通过管道符号(|)来调用的
例如有个字符串类型变量namme,想要获取他的长度,则可以通过{{name | length}}
来获取,length是Jinja2内置好的过滤器
2、自定义过滤器:过滤器本质上是Python的函数,他会把被过滤的值当做第一个参数传给这个函数。函数经过一些逻辑处理后再返回新的值
在过滤器函数写好后,可以通过@app.template_filte
装饰器或者是app.add_template_filter
函数来把函数注册成Jinja2能用的过滤器
def datetime_format(value,format="gY-%d-mH:M"):
return value.strftime (format)
app.add_template_filter(datetime_format,"dformat")
上面我们定义了一个datetime_formmt
的函数,第一个参数是需要被处理的值,第二个参数是时间的格式,并且指定了一个默认值.然后下面通过 app.add_ template_filter
,将datetimeformat
函数注册成了过滤器,并且这个过滤器的名字,叫做dformat
模板文件中,就可以这样类似这样使用了:{{article.pub_date | dformat}}
五、控制语句(基于jinja2)
def control_statement():
age = 18
books = [{"name":"三国演义","author":"罗贯中"},{"name":"水浒传","author":"施耐庞"}]
return render_template("control.html", age=age, books=books)
--control.html中:
1、判断
<body>
{% if age>18 %}
<div>大于18</div>
{% elif age==18 %}
<div>等于18</div>
{% else %}
<div>小于18</div>
{% endif %}
</body>
2、遍历
{% for book in books %}
<div>图书名称: {{ book.name }},图书作者: {{ book.author }}</div>
{% endfor %}
六、模板继承(基于jinja2)-HTML继承
1、引用base.html模板,在顶部引用
{% extends "base.html" %}
2、需要重写的地方,定义成block:title、head、body、footer
,可以在字模板重新写
{% block title %}首页{% endblock %}
{% block title %}
color: red;
{% endblock %}
七、加载静态文件(基于jinja2)
1、一个网页中,除了HTML代码以外,还需要CSS、JavaScript和图片文件才能更加美观和实用。静态文件默认是存放到当前项目的static
文件夹中,如果想要修改静态文件存放路径,可以在创建Flask对象的时候,设置 static folder 参数:
app = Flask(__name__, static_folder = 'C:\static')
2、在HTML模板文件中,可以通过url_for加载静态文件:
<link href="{{url_for('static',filename = 'about.css')}}">
八、Flask-SOLAlchemy基本使用
# 用到的包
pip install SQLAlchemy
pip install flask-sqlalchemy
1、连接MySql
使用Flask-SQLAlchemy 操作数据库之前,要先创建一个由Flask-SOLAlchemy提供的SQLAlchemy类的对象。在创建这个类的时候,要传入当前的app。然后还需要在app.config中设置SOLALCHEMY_DATABASE_URI,来配置数据库的连接
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# config文件中:
# MySQL所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL监听的端口号,默认3306
PORT = 3306
# 连接MySOL的用户名
USERNAME = "root"
# 连接MySQL的密码
PASSWORD = "root"
# MySQL上创建的数据库名称
DATABASE = "database_learn"
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8"
db=SQLAlchemy(app)
with app.app_context():
with db.engine.connect() as conn:
rs = conn.execute("select 1")
print(rs.fetchone()) #(1,)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__'
app.run()
2、ORM模型:
对象关系映射(Object Relationship Mapping),简称ORM,是一种可以用Python面向对象的方式来操作关系型数据库的技术,具有可以映射到数据库表能力的Python类我们称之为ORM模型。
(1)一个ORM模型与数据库中一个表相对应,ORM模型中的每个类属性分别对应表的每个字段,ORM模型的每个实例对象对应表中每条记录
(2)ORM技术提供了面向对象与SOL交互的桥梁,让开发者用面向对象的方式操作数据库
(3)优势:
--开发效率高:几乎不需要写原生SQL语句,使用纯Python的方式操作数据库,大大的提高了开发效率
--安全性高:ORM模型底层代码对一些常见的安全问题,比如SOL注入做了防护,比直接使用SOL语句更加安全
--灵活性强:Flask-SOLAlchemy底层支持SQLite、MySQL、Oracle、PostgreSOL等关系型数据库,但针对不同的数据库,ORM 模型代码几乎一模一样,只需修改少量代码,即可完成底层数据库的更换
(4)例子-创建一个表:
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(100),nullable=False)
password = db.Column(db.String(100),nullable=False)
# 相当于sql: insert into user(username,password) values(法外狂徒张三,1111111);
with app.app_context():
db.create_all
3、ORM增删改查数据
(1)新增数据:
@app.route("/user/add")
def add_user():
# 1.创建ORM对象
user = User(username="法外狂徒张三",password='111111')
# 2.将ORM对象添加到db.session中
db.session.add(user)
# 3.将db.session中的改变同步到数据库中
db.session.commit()
return "用户创建成功!"
(2)查询数据:
ORM 模型都是继承自db.Model,db.Model内置的query属性上有许多方法,可以实现对ORM模型的查询操作。query上的方法可以分为两大类,分别是过滤方法以及提取方法:
提取方法:
query.all()
:获取查询结果集中的所有对象,是列表类型
query.first()
:获取结果集中的第一个对象
query.one()
:获取结果集中的第一个对象,如果结果集中对象数量不等于 1,则会抛出异常
query.one_or_none()
:与one类似,结果不为1的时候,不是抛出异常,而是返回None
query.get(pk)
:根据主键获取当前ORM模型的第一条数据
query.exists()
:判断数据是否存在
query.count()
:获取结果集的个数
过滤方法:
query.filter()
:根据查询条件过滤
query.filter_by()
:根据关键宁参数过滤
query.slice(start,stop)
:对结果进行切片操作
query.limit(limit)
:对结果数量进行限制
query.offset(offset)
:在查询的时候跳过前面offset条数据
query.order_by()
:根据给定字段进行排序
query.group_by()
:根据给定字段进行分组
除了直接使用= =、=外,还可以使用以下常用的过滤条件进行过滤,这些过滤条件通过flter
方法实现
like
:users-User.query.filter(User.username.like("张"))
in
:users-User.query.filter(User.username.in_(["张三","李四","王五"]))
not in
:users-User.query.filter(~User.username.in_(['张三'])
is null
:users=-User.query.filter(User.username.is_(None))
is not null
:users =User.query.filter(User.username.isnot(None))
and
:users=User.query.filter(and_(User.username= ="张三",User.id<10))
or
:users=User.query.filter(or_(User.username= ="张三",User.id<10))
@app.route("/user/query")
def query_user():
# 1.get查找:根据主键查找
users = User.query.get(1)
# 取user中所有数据
users = User.query.all()
# 获取第一条数据
user = User.query.first()
print(f"{user.id}: {user.username}-{user.password}")
# 2.filter_by查找
# Query:类数组
users = User.query.filter_by(username="张三")
for user in users:
print(user.username)
return "数据查找成功!"
(3)修改数据:
@app.route("/user/update")
def update_user():
user= User.query.filter_by(username="张三").first()
user.password = "222222"
db.session.commit()
return "数据修改成功!"
(4)删除数据
# 删除单条数据
user= User.query.get(1)
db.session.delete (user)
db.session.commit()
# 删除多条数据:通过BaseQuery上的delete方法
User.query.filter(User.username.contains("张三")).delete(synchronize_session=False)
db.session.commit()
@app.route("/user/delete")
def delete_user():
user= User.query.get(1)
db.session.delete (user)
db.session.commit()
return "数据删除成功!"
4、表关系:一对一、一对多(多对一)、多对多
(1)外键:在Flask-SQLAchemy 中支持创建ORM模型的时候就指定外键,创建外键是通过db.ForeignKey
实现的
例如:创建一个Article表,有一个author_id字段,通过外键引用user表的id字段
class Article(db.Model):
__tablename__="article"
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
title=db.Column(db.string(200),nullable=False)
content=db.Column(db.Text,nullable=False)
author_id=db.Column(db.Integer,db.ForeignKey("user.id"))
以上代码,除了添加常规title、content属性外,还增加了一个autbor_id,author_id通过db.ForeignKey(“user.id”)
引用了user表的id字段。注意author_id因为引用user表的id字段,所以他的类型必须跟user表的id字段一致
(2)为了达到操作ORM对象就跟操作普通Pytho对象一样,Flask-SQLAlchemy 提供了db.relationship来引用外键所指向的那个ORM模型。在以上的Article模型中,添加dbrelationiship:
class Article(db.Model):
__tablename__="article"
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
title=db.Column(db.string(200),nullable=False)
content=db.Column(db.Text,nullable=False)
author_id=db.Column(db.Integer,db.ForeignKey("user.id"))
author=db.relationship("user")
添加了一个author属性,这个属性通过db.relationship与User模型建立了联系,以后通过Article的实例对象访问author 的时候,比如article.author,那么Flask-SQLAlchemy会自动根据外键author_id从user表中寻找数据,并形成User模型实例对象
如通过创建Article对象,并通过访问Article实例对象上的author属性来关联User对象:
@app.route('/article/add')
def article_add():
user = User.query.first()
article = Article(title="aa",content="bb",author=user)
db.session.add(article)
db.session.commit()
(3)为了实现双向关系绑定,我们还需要在 User模型上添加一个dbrelationship 类型的articles 属性并且在 User模型和Article模型双方的dbrelationship上,都需要添加一个 back populates 参数,用于绑定对方访问自己的属性:
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.string(100))
password = db.Column(db.String(100))
articles = db.relationship("Article",back_populates="author")
class Article(db.Model):
__tablename__ = "article"
id = db.Column(db.Integer, primary_key=True,autoincrement=True)
title = db.Column(db.string(200),nullable=False)
content = db.Column(db.Text,nullable=False)
author_id = db.Column(db.Integer,db.ForeignKey("user.id"))
author = db.relationship("user",back_populates="articles")
在User 端绑定了articles 属性后,现在双方都能通过属性直接访问到对方了:
user = User.query.first()
for article in user.articles:
print(article.title)
(4)还可以通过只在一个模型上定义db.relationship类型属性,并且传递backref参数,来实现双向绑定
backref:会自动的给User模型添加一个articles的属性,用来获取文章列表
author = db.relationship("User",backref="articles")
(5)级联操作
级联操作(Cascade)是在操作某个对象的时候,相关联的对象也会进行对应的操作。在数据库层面的级联操作包括级联删除,级联更新等。Flask-SQLAlchemy 提供了比数据库级更强大的级联操作,定义级联操作是通过在 db.relationship 传递 cascade 参数实现的,这个参数的值可以为all、save-update、merge、refresh-expire、expunge、delete中的一个或者是多个,如果是多个,则通过英文逗号隔开,比如”save-update,delete”。谁设置了cascade 参数,谁就是父表,父表数据发生变化,相关联的从表也会执行相应操作
class Category(db.Model):
__tablename__ = "category"
id = db.Column(db.Integer,primary_key-True,autoincrement=True)
name = db.Column(db.string(100))
newses = db.relationship("News",back_populates="category")
class News(db.Model):
__tablename__ = "news"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.string(100))
(6)ORM模型映射成表的三步:
# 1.flask db init:这步只需要执行一次,初始化
# 2.flask db migrate:识别ORM模型的改变,生成迁移脚本
# 3.flask db upgrade:运行迁移脚本,同步到数据库中
我之前报错:Fatal error in launcher: Unable to create process using '"d:\python36\python.exe" "D:\Python\Scripts\flask.exe" flask db init': ???????????
指定python能解决,运行时加python -m ,如:python -m flask db init
九、邮件
1、pip install flask-mail
十、常用方法:
1、render_template:返回HTML模板
2、用到的包:
pip install flask
pip install SQLAlchemy:数据库
pip install flask-sqlalchemy:数据库
pip install flask-mail:邮件
pip install email_validator:邮件,校验器
未完待续。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~