flask01

1、第一个flask文件

from flask import Flask

#使用flask类创建一个app对象
#__name__: 代表当前app.py这个模块
# 1.以后出现bug,可以快速定位
# 2. 对于寻找模板文件,有一个相对路径
app = Flask(__name__)


#创建一个路由和视图函数的映射
#http://www.baidu.com
@app.route('/')
def hello_world():  # put application's code here
    return 'Hello haha哈!'

#1.dubug 模式
    #直接刷新,无需重启服务器,如果开发时出现bug,在浏览器上就能看见出错信息

#2.修改host
    #让其他电脑能访问到我电脑上的flask项目
#3.修改端口号
    #防止端口占用,可以通过修改port监听其他端口
if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')

2、URL与视图映射

from flask import Flask,request

app = Flask(__name__)


#  URL参数可以指定类型个性化定制String,int,float,path……
@app.route('/blog/<int:blog_id>')
def blog_detail(blog_id):
    return "您访问的博客是:%s" % blog_id

# /book/list:会给我返回第一页的数据
# /book/list?page=2: 获取第二页的数据
@app.route('/list')
def book_list():
    # arguments:参数
    #request.args:类字典类型
    page = request.args.get('page',default = 1,type=int)
    return f"您获取的是第{page}的图书列表!"

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')

3、jinja2模板渲染

Jinja2 是一种现代的、设计优雅的模板引擎,它是 Python 的一部分,由 Armin Ronacher 开发。Jinja2 允许你在 HTML 文档中嵌入 Python 代码,以及使用变量、控制结构和过滤器来动态生成内容。它的语法简洁清晰,易于学习和使用。
(1)模版传递参数

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    # 定义要传递给模板的参数
    user = {'username': 'John', 'age': 30}
    fruits = ['Apple', 'Banana', 'Orange', 'Mango']
    return render_template('index.html', user=user, fruits=fruits)

if __name__ == '__main__':
    app.run(debug=True)
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
    <title>Flask Template Example with Parameters</title>
</head>
<body>
    <h1>Hello, {{ user.username }}!</h1>
    <p>You are {{ user.age }} years old.</p>

    <h2>Favorite Fruits:</h2>
    <ul>
    {% for fruit in fruits %}
        <li>{{ fruit }}</li>
    {% endfor %}
    </ul>
</body>
</html>
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    # 定义要传递给模板的参数
    data = {
        'user': {'username': 'John', 'age': 30},
        'fruits': ['Apple', 'Banana', 'Orange', 'Mango']
    }
    return render_template('index.html', **data) # 这里使用**进行解包,这是Python3的特性


if __name__ == '__main__':
    app.run(debug=True)
class User:
    def __init__(self,username,email):
        self.username =username
        self.email = email


@app.route('/<blog_id>')
def blog(blog_id):
    user = User(username='leican', email='123456@com')
    return render_template("index.html",blog_id = blog_id,user=user)

(2)使用url_for 参数

# app.py
from flask import Flask, render_template, url_for

app = Flask(__name__)

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

@app.route('/h')
def hello():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True)
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
    <title>Flask Template Example with url_for()</title>
</head>
<body>
    <h1>Hello, Flask!</h1>
    <p>This is a template example.</p>

    <p><a href="{{ url_for('hello') }}">Say Hello</a></p>
</body>
</html>

(3) include模板导入

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>include</title>
</head>
<body>
<div class="container">
    {% include 'header.html' %}

    <h4>主题内容</h4>

    {% include 'footer.html' %}
</div>
</body>
</html>

(4) 使用静态资源
一旦你有了静态资源文件夹,你可以在模板中通过使用 url_for 函数来引用这些静态资源。例如,在模板中引用样式表文件 style.css:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Flask App</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>Welcome to My Flask App</h1>
    <img src="{{ url_for('static', filename='img/logo.png') }}" alt="Logo">
    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>

在这个示例中,url_for('static', filename='path/to/resource') 函数用于生成静态资源的 URL。在调用时,第一个参数 'static' 是 Flask 中默认用于静态资源的端点,而第二个参数 'filename' 是静态资源的路径。

可调整静态文件位置

app = Flask(__name__, static_folder="static2")  # 设置静态文件夹地址为 static2
# 第二种方式 app.static_folder = 'static2'

4.jinja2语法
Jinja2 是一种现代的、设计优雅的模板引擎,它为开发者提供了一种简单而强大的方式来创建动态内容。Jinja2 的语法清晰简洁,易于学习和使用。在这里,我将详细介绍 Jinja2 的主要语法元素:
(1) 定义变量

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask Template Example</title>
</head>
<body>
    {% set title = "Title" %}

    {% with subtitle="subtitle" %}
        {% set combined_title = title + " " + subtitle %}

        <h1>{{ combined_title }}</h1>

        {% with paragraph="This is the paragraph content of my website." %}
            <p>{{ paragraph }}</p>
        {% endwith %}
    {% endwith %}

    <!--  此处出了with的范围则不可使用其中变量subtitle等  -->
</body>
</html>

with只在范围内可用, set则是全局, with和 set可以结合使用
(2)流程控制
Jinja2 支持常见的控制结构,如条件语句和循环。控制结构使用 {% ... %} 包裹

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    # 假设这是从后端传递给前端的数据
    user = {'username': 'Alice', 'age': 30}
    return render_template('index.html', user=user)

if __name__ == '__main__':
    app.run(debug=True)
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
    <title>选择结构示例</title>
</head>
<body>
    <h1>欢迎访问我的网站!</h1>
    <p>用户信息:</p>
    <ul>
        <li>用户名:{{ user.username }}</li>
        <li>年龄:{{ user.age }}</li>
    </ul>

    {% if user.age < 18 %}
        <p>您未满18岁,属于未成年人。</p>
    {% elif user.age >= 18 and user.age < 60 %}
        <p>您已满18岁,属于成年人。</p>
    {% else %}
        <p>您已年满60岁,属于老年人。</p>
    {% endif %}
</body>
</html>

(3)过滤器
过滤器允许你在输出中应用转换。它们以管道符 | 的形式使用。


自定义过滤器

from flask import Flask,render_template,url_for
app = Flask(__name__)

# @app.template_filter("reverse") # 注册自定义过滤器
def reverse_filter(s):  # 自定义过滤器函数
    return s[::-1]

app.add_template_filter(reverse_filter,'dformat')
app.jinja_env.filters['reverse'] = reverse_filter  # 注册自定义过滤器的第二种方法
# 路由
@app.route('/')
def index():
    # 在模板中使用自定义过滤器
    message = "Hello, World!"
    some = [1,3,"哈哈",9,"唯一",True]
    return render_template('index.html', message=message,some=some)

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title >LC首页</title>
</head>
<body style="color: aqua">
首页
{{ message }}
<hr>
{{ some|reverse }}
<hr>
<h3>{{ message|dformat }}</h3>
</body>
</html>

使用装饰器或者 app.jinja_env.filters都可以设置过滤器
(4)定义宏
宏类似于函数,允许你定义可重用的代码块。注意宏没有返回值

from flask import Flask, render_template

app = Flask(__name__)


# 定义一个简单的宏,用于在模板中显示消息
@app.template_global()
def display_message(message):
    return f"Message: {message}"


@app.route('/')
def index():
    return render_template('index.html', message="Hello, world!")


if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask Template Example</title>
</head>
<body>
    <!-- 使用宏显示消息 -->
    {{ display_message(message) }}
</body>
</html>

5、 Flask连接MySQL
SQLAlchemy是一个关系型数据库框架,它提供了高层的ORM和底层的原生数据库的操作。flask-sqlalchemy是一个简化了SQLAlchemy操作的flask扩展。

SQLALchemy实际上是对数据库的抽象,让开发者不用直接和SQL语句打交道,而是通过Python对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.sql import text

app = Flask(__name__)

HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = 'leican0605'
DATABASE = 'studentms'

app.config[
    'SQLALCHEMY_DATABASE_URI'] = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4'

db = SQLAlchemy(app)
# app.app_context(): Flask 应用需要运行在 "应用上下文" 中才能访问配置和扩展(如 db)。with 语句确保上下文在代码块内有效。
with app.app_context():
    # db.engine.connect(): 通过 SQLAlchemy 的数据库引擎(db.engine)创建一个新的数据库连接。
    # with 语句确保连接在使用后自动关闭,避免资源泄漏。
    with db.engine.connect() as conn:
        # text('SELECT 1+10'): 将纯文本 SQL 语句包装成 SQLAlchemy 可执行的格式(防止 SQL 注入)。测试用的简单 SQL 查询,计算 1+10 的值
        # conn.execute(): 执行 SQL 语句,返回一个结果集对象 rs(类型为 ResultProxy 或 CursorResult)。
        rs: object = conn.execute(text('SELECT 1+10'))
        print(rs.fetchone()) #从结果集中提取第一行数据(这里是 (11,),因为 1+10=11)。

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

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

在Flask-SQLAlchemy中,插入、修改、删除操作,均由数据库会话管理。会话用db.session表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用commit()方法提交会话。

数据库会话是为了保证数据的一致性,避免因部分更新导致数据不一致。提交操作把会话对象全部写入数据库,如果写入过程发生错误,整个会话都会失效。

数据库会话也可以回滚,通过db.session.rollback()方法,实现会话提交数据前的状态。

在Flask-SQLAlchemy中,查询操作是通过query对象操作数据。最基本的查询是返回表中所有数据,可以通过过滤器进行更精确的数据库查询。


ORM模型
一个ORM模型与数据库中的一张表相对应,ORM模型的每个类的属性分别对应表的每个字段,ORM模型的每个实例化对象对应表中每条记录。ORM模型提供了面向对象与SQL交互的桥梁。

使用python创建数据库表

class student(db.Model):
    __tablename__ = 'student'
    id = db.Column(db.Integer,primary_key = True)  #映射到表对象
    name = db.Column(db.String(64),nullable=False)
    password = db.Column(db.String(64),nullable=False)

    def __repr__(self):
        return f'<user {student.sname}'
with app.app_context():
    db.create_all()

往数据库表中添加对象

@app.route('/add')
def add_student():
    # 1、创建ORM对象
    user1  = student(id = 1,name = "雷灿", password = "123")
    user2 = student(id=2, name="pass", password="1230")
    user3 = student(id=3, name="fazem", password="2025")
    # 2、将ORM对象添加到db.Session中
    db.session.add(user1)
    db.session.add(user2)
    db.session.add(user3)
    # 3.将db.session中的改变同步到数据库中
    db.session.commit()
    return "用户添加成功"
# 插入一条数据
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
#再次插入一条数据
ro2 = Role(name='user')
db.session.add(ro2)
db.session.commit()
us1 = User(name='wang',email='wang@163.com',pswd='123456',role_id=ro1.id)
us2 = User(name='zhang',email='zhang@189.com',pswd='201512',role_id=ro2.id)
us3 = User(name='chen',email='chen@126.com',pswd='987654',role_id=ro2.id)
us4 = User(name='zhou',email='zhou@163.com',pswd='456789',role_id=ro1.id)
db.session.add_all([us1,us2,us3,us4])
db.session.commit()

查询

@app.route('/query')
def query_student():
    # 1.get查找:根据主键查找
    student1 = student.query.get(2)
    print(f"{student1.name} + {student1.password}")
    # 2. filter_by查找 (Query对象)
    students = student.query.filter_by(name = "雷灿")
    for studentm in students:
        print(f"{type(studentm)} ")
    #3、 first()返回查询到的第一个对象,all()返回查询到的所有对象
    student2 = student.query.first()

    # 4、 filter模糊查询,返回名字结尾字符为g的所有数据。
    students1 = student.query.filter(student.name.endswith('f')).all()
    for student0 in students1:
        print(f"{student0.name} ")
    # 5、逻辑非,返回名字不等于wang的所有数据。
    students2 = student.query.filter(student.name != '雷灿').all()

    for student9 in students2:
        print(f"{student9.name} ")
    return  "查找成功"

逻辑非,返回名字不等于wang的所有数据。
User.query.filter(User.name!='wang').all()

逻辑与,需要导入and,返回and()条件满足的所有数据。
from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()

逻辑或,需要导入or_
from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()

修改

# User.query.filter_by(name='zhang').update({'name':'li'})
@app.route('/update')
def update_student():
    student1 =student.query.filter_by(name = "pass")[0]
    student1.name = "LC"
    db.session.commit()
    return "数据修改成功"
posted @ 2025-04-18 17:44  fazem  阅读(9)  评论(0)    收藏  举报