DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • Django

  • 第一次学drf

  • 第二次学drf

  • 温故知新

  • flask

    • flask使用

    • flask源码

      • 面试题
      • 快速使用
      • 数据库链接池
      • flask的使用
        • werkzeug返回值
        • 静态文件的处理
        • 配置文件相关
          • 基于全局变量
          • 基于类的方式
        • 路由系统
          • 路由加载的源码流程
          • 路由的两种写法
          • 动态路由
        • 视图
          • FBV
          • CBV
          • CBV源码
        • 模版
        • 特殊装饰器-中间件
        • 补充: threading.local
      • flask上下文管理
      • 使用简记
  • 后端
  • flask
  • flask源码
DC
2024-09-24
目录

flask的使用

前面是Flask的快速使用, 这里完善一下Flask的使用!!

image-20240925085704897


# werkzeug返回值

werkzeug不依赖于flask, 自己就可以完成一个网站.. 那它的返回值咋写呢? 我们可以探究下flask的源码!

通过flask源码反推wsgi返回值!! 看源码的过程 在pycharm里不断跳转 注重其返回值就行!!
★ 这个技巧务必掌握! 看返回值 --〉看调用了谁 --〉自己自定义修改扩展..

image-20240924094008969

ok, 我们来测试下, 是完全没问题的!! 哈哈哈哈 有点意思..

from werkzeug.serving import run_simple
from werkzeug.wrappers import Response  # Response的父类是BaseResponse,使用BaseResponse也是可以的!!


def func(environ, start_response):
    return Response("Hello World!!")(environ, start_response)


if __name__ == "__main__":
    run_simple('localhost', 5001, func)
1
2
3
4
5
6
7
8
9
10

# 静态文件的处理

先来看看规则

image-20240924113511239

但一般情况下, static_folder和static_url_path我们都使用默认值即可!! 标准写法如下:

# 尽管Flask的static_url_path的默认参数值为None,但实验下来,若不显式指定前缀,则前缀默认为/static
app = Flask(__name__,template_folder='templates',static_folder='static')

<img src="{{ url_for('static',filename='keep1.png')}}" alt="">  # 嵌套了目录的话 xx/xx/keep1.png

-- ★ 当静态文件目录名改变后,img的地址会 [动态] 跟着变!! eg: static_folder='yy' 则对应前缀默认为'/yy'
1
2
3
4
5
6

# 配置文件相关

Django支持第一种,Flask第一种第二种都支持!!

# 基于全局变量

image-20240924141345291

★ 在本地,一般我们会在settings.py中写公共的配置,在localsettings.py中写本地数据库等私密的配置!!
  - 当我们git上传项目到github时
    即在执行git add . 之前, 需将localsettings.py加入忽略文件.gitigonre!! config/localsettings.py
  - 然后服务器拉取github中的项目进行部署. 我们需要在服务器上自己创建一个localsettings.py,里面写入线上数据库的配置!!  
  - 新员工从github上拉取项目进行开发,需自己进行数据库的配置在本地进行测试开发,线上数据库它是不知道,动不了的!!
    经过上述的过程,保密性很好!!
    
  - 当然,我们可以在settings.py中写上测试数据库的配置!这样更方便大家开发,大家就不用在本地弄数据库了!!

  
★ 特别注意!!配置文件中的变量名需要大写!!
1
2
3
4
5
6
7
8
9
10
11

# 基于类的方式

BaseSetting中写公共的配置!

image-20240924144500917


# 路由系统

# 路由加载的源码流程

image-20240924164207425

step1: 将url和函数打包成为 rule 对象
step2: 将rule对象添加到 map 对象中
 
So,以后我们可以 通过 app.url_map 拿到 map对象, 里面有一大推 路由与视图的对应关系!!
当请求进来,进行路由匹配时,就会去app.url_map中找!!
1
2
3
4
5

# 路由的两种写法

def index():
    return render_template('index.html')
app.add_url_rule('/index', 'index', index)


# - 公司里一般用这种方式
@app.route('/login')
def login():
    return render_template('login.html')
1
2
3
4
5
6
7
8
9

# 动态路由

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


@app.route('/login/<name>')
def login(name):
    print(type(name))  # str
    return render_template('login.html')


@app.route('/login/<int:name>')
def login(name):
    print(type(name))  # int
    return render_template('login.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

flask默认不支持正则路由, 当然, 你可以自己改下源码来实现.. 因为正则路由基本用不到, 我了解了下, 在此处就不总结该方式了..


# 视图

# FBV

# - 方式一
def index():
    return render_template('index.html')
app.add_url_rule('/index', 'index', index)


# - 方式二
@app.route('/login')
def login():
    return render_template('login.html')
1
2
3
4
5
6
7
8
9
10

# CBV

from flask import Flask, views

app = Flask(__name__)


def test1(func):
    def inner1(*args, **kwargs):
        print('before1')
        result = func(*args, **kwargs)
        print('after1')
        return result

    return inner1


def test2(func):
    def inner2(*args, **kwargs):
        print('before2')
        result = func(*args, **kwargs)
        print('after2')
        return result

    return inner2


class UserView(views.MethodView):
    methods = ['GET', "POST"]  # 不写该类变量的话,默认只支持GET

    # view = test2(test1(view)) --> view = test2(inner1)  --> view = inner2
    decorators = [test1, test2]

    def get(self, pk):
        print('get')
        return 'get'

    def post(self, pk):
        print('post')
        return 'post'


app.add_url_rule('/user/<int:pk>', view_func=UserView.as_view('user'))  # 'user' 就是 endpoint

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


"""GET请求和POST请求访问 http://127.0.0.1:5000/user/1 都会打印以下内容
before2
before1
post
after1
after2
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# CBV源码

Flask整个CBV的源码逻辑 跟 Django的CBV 源码逻辑 并无出入, 一模一样!
as_view -- view -- 路由匹配成功后,加括号执行view -- view里做了两件事, 实例化当前视图类 + 执行dispatch方法 -
在dispatch方法中 反射执行了路由匹配的 视图函数!!

△ 注意: 在Flask的CBV里,还有个很好玩的地方: 可以给视图函数添加装饰器..

image-20240924174638043


# 模版

image-20240924190032052

注意: 若使用了蓝图, 那么 定义全局模板方法 的应用范围只有本蓝图!!


# 特殊装饰器-中间件

@app.before_request、@app.after_request 能实现跟 Django中间件一样的执行流程!!

我实验过了, Flask的FBV、CBV都可以使用这两个特殊的装饰器!!

image-20240924195852298

from flask import Flask, views

app = Flask(__name__)


@app.before_request
def f1():
    print('f1')


@app.before_request
def f2():
    if request.path == "/login":  # !!读session会话保持,读白名单等
        return
    print('f2')


@app.after_request
def f10(response):
    print('f10')
    return response


@app.after_request
def f20(response):
    print('f20')
    return response


@app.route('/index')
def index():
    print("index")
    return "hello world"


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


"""
f1
f2
index
f20
f10
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

扩展:

@app.before_request
def f1():
    print('f1')
1
2
3

等同于

def f1():
    print('f1')
    
f1 = app.before_request(f1)  
# app.before_request(f1) 这样写也可以,因为你看源码,它是把f1添加到一个列表中了..整个中间件过程用的是列表中的.返回的f1没用..
1
2
3
4
5

# 补充: threading.local

若多线程来, 它会为每个线程独立开辟一个小区域, 存储当前线程的值!!
Flask源码里没有用它, 但Flask基于线程ID自己实现了类似的功能!!

image-20240925084448836


数据库链接池
flask上下文管理

← 数据库链接池 flask上下文管理→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式