flask 之(五) --- 对象|钩子|拆分

内置对象

  • request:  请求的所有信息
  • session     服务端会话技术的接口
  • config:      当前项目的配置信息,模板中可以直接使用
  • g:global  在单次请求过程中,实现全局数据共享(可以帮助开发者实现跨函数传递数据)
from flask import Blueprint, render_template, g
from .models import User

user_blue = Blueprint('user_blue',__name__,url_prefix="/users/")

@user_blue.route('/')
def hello_world():
    return 'User Index!'

@user_blue.route('/create/')
def create():
    # g的信息即使没有被返回渲染,也可以在html中获取到
    g.msg = "g的信息"
    return render_template('index.html')
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Index</title>
 6 </head>
 7 <body> # 获取全局变量的值
 8 <h1>{{ g.msg }}</h1>
 9 </body>
10 </html>
  • config 或者app 

  config表示当前运行的项目。遍历config时是获取当前运行的App的配置 [配置应该是有价值的]

  在python代码中current_app.config,当前运行的app。用在函数中,使用记得是在初始化完成之后

1 <body>
2 <ul>
3     {% for foo in config %}
4         <li>{{ foo }}</li>
5     {% endfor %}
6 </ul>
7 </body>

钩子函数

编程模型 :

  • OOP:   面向对象编程;POP:   面向过程编程
  • AOP: 面向切面编程;IOP:  面向接口编程

面向切面: 

  在不修改原有逻辑代码的基础上。动态的去添加一些功能或者控制逻辑(装饰器类似)

  动态介入到既有流程中,去监控或者去获取我们想要的数据

  蓝图和app上都有钩子函数,app上的钩子优先级更高一些;蓝图只能处理本蓝图内容的信息

  

重要概念:

  切面:切开后可以获取的东西叫切面。(在flask中叫做钩子函数)

     请求前切面获取:  request

     请求后切面获取:  request、response

     请求异常切面获取: exception、request

  切点:可切的地方叫切点。请求前、请求后、请求异常

     请求前切点:  @user_blue.before_request

     请求后切点:  @user_blue.before_request

     请求异常切点: @user_blue.errorhandler(500)

 1 """
 2 常用请求钩子:
 3 
 4     before_first_request:     在处理app第一个请求前运行。
 5 
 6     before_request:        在每次请求前运行。
 7 
 8     after_request:        如果处理逻辑没有异常抛出,在每次请求后运行。
 9 
10     teardown_request:       在每次请求后运行,即使处理发生了错误。
11 
12     teardown_appcontext:     在应用上下文从栈中弹出之前运行
13 """
 1 # 定义钩子函数:相当于django中的中间件
 2 
 3 # before_request装饰的方法会加载到app的before_request_funcs列表中,按加载的顺序依次执行,不需要参数
 4 @app.before_request
 5 def test_before_request():
 6     print('before_request:2')
 7 
 8 # before_first_request装饰的函数加载到before_first_request_funcs列表中,只不过在app第一次接收到请求后执行,其他时候不再执行
 9 @app.before_first_request
10 def test_before_first_request():
11     print('before_first_request:1')
12 
13 # after_request装饰的函数加载到after_request_funcs列表中,传入的参数是response对象,可以对其进行拦截修改,必须返回一个response对象
14 @app.after_request
15 def test_after_request(resp):
16     print(resp)
17     print('after_request:3')
18     return resp
 1 @bp.before_request
 2 def test_before_request():
 3     """
 4     每个视图函数执行之前,都会执行此函数
 5     根据业务决定是否有返回值
 6     :return:
 7     """
 8     print('in before request')
 9     g.start_time = time.time()
10 
11     # before_request 可以用在对所有请求的登录认证中
12     # 1、通过session,获取用户id
13     # 2、根据用户id查找用户对象
14     # 3、如果用户id合法,则认为登录合法
15     # 4、在后续的所有视图函数中,可以直接使用 g.user 获得当前登录的user对象
16     # uid = session.get('uid')
17     # user = User.query.get(uid)
18     #
19     # if user:
20     #     g.user = user
21     #     g.is_login = True
22     # else:
23     #     g.user = None
24     #     g.is_login = False
25 
26 
27 
28 @bp.after_request
29 def test_after_request(response):
30     print('in after request')
31     start_time = g.start_time
32     exec_time = time.time() - start_time
33     print('exec_time:', exec_time)
34     return response
钩子和对象
  • 内置蓝图钩子 [请求前] 
 1 from flask import Blueprint, render_template, g
 2 from .models import User
 3 
 4 user_blue = Blueprint('user_blue',__name__,url_prefix="/users/")
 5 
 6 @user_blue.route('/')
 7 def hello_world():
 8     return 'User Index!'
 9 
10 @user_blue.route('/create/')
11 def create():
12     
13     print('create视图函数,在钩子函数执行之后执行')
14     
15     # 接收before钩子函数传递过来的数据
16     print("before钩子函数传递过来的数据:",g.data)
17     
18     # g的信息即使没有被返回渲染,也可以在html中获取到
19     g.msg = "g的信息"
20     return render_template('index.html')
21 
22 # 切面 即钩子函数
23 @user_blue.before_request
24 def before():
25     
26     print("before钩子函数,在路由函数执行之前执行")
27     
28     # 向create视图函数中传递数据
29     g.data = "钩子函数 给 视图函数 的数据"
  • 内置蓝图钩子 [请求后]
 1 from flask import Blueprint
 2 from .models import Movie
 3 
 4 movie_blue = Blueprint("movie_blue",__name__,url_prefix="/movies/")
 5 
 6 @movie_blue.route('/')
 7 def index():
 8     return "Movie Index"
 9 
10 @movie_blue.before_request
11 def before():
12     print("before")
13 
14 @movie_blue.after_request
15 def after(resp):  # 切开时获取到的返回值作为参数
16     print("after")
17              # 切开后,需要把切之前要返回的信息接着返回出去
18     return resp 
  • 内置蓝图钩子 [异常捕获]
 1 from flask import Blueprint
 2 from .models import Movie
 3 
 4 movie_blue = Blueprint("movie_blue",__name__,url_prefix="/movies/")
 5 
 6 @movie_blue.route('/')
 7 def index():
 8     return "Movie Index"
 9 # 请求前
10 @movie_blue.before_request
11 def before():
12     print("before")
13 # 请求后
14 @movie_blue.after_request
15 def after(resp):
16     print("after")
17     # 切开后,需要把切之前要返回的信息接着返回出去
18     return resp
19 # 异常捕获
20 @movie_blue.errorhandler(500)   # 错误码
21 def error500(exce):         # 获取异常参数
22     print(type(exce))
23     return "异常信息屏蔽,返回到首页"

  可以在项目的目录下新建一个 middleware.py 文件。将切面编程代码编写在middleware文件中。

  然后在__init__.py文件中把中间件middleware加载进来:load_middleware(app)。改成全局的中间件,优先级更高

  在middleware.py 文件中,声明一个 load_mindleware(app)函数,导入相应的包,然后在此函数下写中间件视图函数

1 def load_middleware(app):
2 
3     @app.before_request()
4     def before():
5         print("before") 

项目拆分 

  在开发过程中多人合作完成,就需要考虑项目的重构性、扩展性。在一个文件中写代码,是非常不理想的。就需要对文件进行拆分。

  拆分:

    首先有一个文件的程序,名字就叫这个项目的名字。通过flask-script可以将这个文件改变成统筹管理这个项目的文件,

    将此文件名字改成 manage。用它来统筹管理我们这个项目。然后新建一个名为App包文件,用来存放此项目的文件

    在包文件中,通常将创建flask的过程写在 __init__.py 文件中,天然单例首先被调用。

    在setting.py文件中做配置信息,在__init__ 中加载配置文件进来。

    在extension.py文件中做扩展库的信息,在__init__中初始化扩展库。

    在views.py文件中做视图函数信息,在__init__中初始化路由,尽量最后初始化路由(是web的入口,在启动时需要其他信息加载好)

    在model.py文件中操作数据信息,views.py 文件操作 model.py ;model.py 还需要extenson扩展库文件中的db

  总结:

     配置要优先于初始化。首先初始化 配置信息;然后初始化 扩展库;最后初始化 路由。启动项目的时候从manage.py开始启动 

     启动的时候首先创建Flask对象,然后对Flask对象的配置进行各种初始化,加载完初始化后去加载扩展库,最后初始化路由。 

  分析:

    manager.py文件中创建Flask的app实例(对象)。通过App/__init__.py文件中的 create_app 函数来创建Flask的App实例。

      并且把创建好的app实例交给Manager来管理 

    App/__init__.py文件中加载初始化各种配置:创建app实例、加载配置文件、加载扩展库文件、加载路由(蓝图)。

      创建app实例:通过 create_app 函数来创建Flask的app实例(对象)。

      加载配置文件:通过 config.from_object(Config) 加载对象的方式加载setting.py中创建的配置类Config对象

      加载扩展文件:通过 init_ext(app) 函调用的方式,将app实例以参数的形式传入到扩展文件extension.py文件中的init_ext函数中。

             对app实例进行扩展信息初始化。通过这种方式避免循环导入的问题

      加载路由文件:通过 init_blue(app) 函数调用的方式,将app实例以参数的形式传入到视图views.py文件中。 在init_blue函数中,对app进行(蓝图)初始化。

             避免循环导入问题的出现

  坑点:

    在使用views文件中的视图函数创建数据库表的时候,需要将models文件中的表导入到视图文件中。

    即:views.py 文件中导入:from App.models import User。不然无法识别需要创建的该表的信息。

    

  •  manage.py 文件
 1 """ manage.py """
 2 
 3 import os
 4 from flask_script import Manager
 5 from App import create_app
 6 
 7 # 从系统环境中获取参数FLASK_ENV的值给env,判断是什么环境下的服务器
 8 # 避免外人修改代码,方便代码放在什么环境服务器下,就在什么环境下运行
 9 # 在系统终端 vim .bashrc 编写系统环境变量:#FLASK_ENV。export FLASK_ENV = "develop" 保存退出
10 env = os.environ.get("FLASK_ENV") or 'default'
11 
12 # 首先创建一个flask对象、加载配置、加载扩展库、初始化路由
13 app = create_app(env)
14 # flask-scripy扩展
15 manager = Manager(app)
16 
17 if __name__ == '__main__':
18     manager.run()
  • __init__.py
 1 ''' __init__.py '''
 2 from flask import Flask
 3 from App.settings import Config, envs
 4 from App.extension import init_ext
 5 from App.views import init_blue
 6 
 7 def create_app(env):
 8 
 9     # 创建Flask对象
10     app = Flask(__name__)
11 
12     # 加载初始化配置。 从类对象中加载。env参数确定在什么环境下的
13     app.config.from_object(envs.get(env))
14 
15     # 加载初始化扩展库。通过懒加载的方式加载(调用函数时参数的传递)
16     init_ext(app)
17 
18     # 加载初始化路由器。通过懒加载的方式加载(调用函数时参数的传递)
19     init_blue(app)
20 
21     return app
  • settings.py
 1 ''' settings.py '''
 2 
 3 # 对连接数据库的配置信息进行格式化整理
 4 def get_db_uri(dbinfo):
 5     database = dbinfo.get("DATABASE")
 6     driver = dbinfo.get("DRIVER")
 7     user = dbinfo.get("USER")
 8     password = dbinfo.get("PASSWORD")
 9     host = dbinfo.get("HOST")
10     port = dbinfo.get("PORT")
11     name = dbinfo.get("NAME")
12     return "{}+{}://{}:{}@{}:{}/{}".format(database,driver,user,password,host,port,name)
13 
14 
15 # 配置信息初始化
16 class Config:
17     SECRET_KEY = 'asdfghjjkl'  # 随机值。系统可以基于一个密码随机生成随机值,这个值可以用来做密钥:
18     DEBUG = False
19     TESTING = False
20     SQLALCHEMY_TRACK_MODIFICATIONS = False
21 
22 
23 # 开发环境
24 class DevelopConfig(Config):
25     DEBUG = True
26     # 数据库信息配置
27     dbinfo = {
28         "DATABASE": "mysql",
29         "DRIVER":"pymysql",
30         "USER": "root",
31         "PASSWORD": "guoyapeng",
32         "HOST": "localhost",
33         "PORT": "3306",
34         "NAME": "FlaskModel",
35     }
36     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
37 # 测试环境
38 class TestingConfig(Config):
39     TESTING = True
40     # 数据库信息配置
41     dbinfo = {
42         "DATABASE": "mysql",
43         "DRIVER":"pymysql",
44         "USER": "root",
45         "PASSWORD": "guoyapeng",
46         "HOST": "localhost",
47         "PORT": "3306",
48         "NAME": "FlaskModel",
49     }
50     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
51 # 演示环境
52 class StagingConfig(Config):
53     # 数据库信息配置
54     dbinfo = {
55         "DATABASE": "mysql",
56         "DRIVER":"pymysql",
57         "USER": "root",
58         "PASSWORD": "guoyapeng",
59         "HOST": "localhost",
60         "PORT": "3306",
61         "NAME": "FlaskProject",
62     }
63     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
64 # 生产环境
65 class ProductConfig(Config):
66     # 数据库信息配置
67     dbinfo = {
68         "DATABASE": "mysql",
69         "DRIVER":"pymysql",
70         "USER": "root",
71         "PASSWORD": "guoyapeng",
72         "HOST": "localhost",
73         "PORT": "3306",
74         "NAME": "FlaskModel",
75     }
76     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
77 
78 # 获取在什么环境下,不同环境下数据库不同
79 envs = {
80     "develop":  DevelopConfig,
81     "texting":  TestingConfig,
82     "staging":  StagingConfig,
83     "product":  ProductConfig,
84     "default":  ProductConfig,
85 }
  • extension.py
 1 ''' extension.py '''
 2 from flask_sqlalchemy import SQLAlchemy
 3 from flask_migrate import Migrate
 4 
 5 db = SQLAlchemy()
 6 migate  = Migrate()
 7 
 8 # 通过写一个函数,使用函数传参数的形式将app传递过来。然后db利用app进行初始化
 9 def init_ext(app):
10     db.init_app(app) # db需要使用传过来的参数app来进行初始化
11     migate.init_app(app,db)
  • models.py
1 ''' models.py '''
2 from App.extension import db
3 
4 class User(db.Model):
5     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
6     name = db.Column(db.String(32),unique=True)
7     password = db.Column(db.String(32))
  • views.py 
 1 ''' views.py '''
 2 from flask import Blueprint
 3 from App.extension import db
 4 from App.models import User
 5 
 6 blue = Blueprint('blue',__name__)
 7 def init_blue(app):
 8     app.register_blueprint(blueprint=blue)
 9 
10 
11 @blue.route('/')
12 def hello_world():
13     return 'Hello index!'
14 
15 @blue.route('/create/')
16 def create():
17     db.create_all()
18     return '创建成功'

 视图拆分

  选中views.py文件,右击选择Refactor选项,然后选择Convert To Python Package选项。将原来的views.py文件转换成一个包文件。再在这个包文件中去新建需要的view视图文件。

  • __init.py__
1 from App.views.movie_view import movie_blue
2 from App.views.user_view import user_blue
3 
4 # 蓝图注册初始化
5 def init_blue(app):
6     app.register_blueprint(blueprint=user_blue)
7     app.register_blueprint(blueprint=movie_blue)
  • user_view.py
 1 from flask import Blueprint
 2 from App.extension import db
 3 from App.models import User
 4 
 5 user_blue = Blueprint('user_blue',__name__,url_prefix="/users/")
 6 
 7 @user_blue.route('/')
 8 def hello_world():
 9     return 'User Index!'
10 
11 @user_blue.route('/create/')
12 def create():
13     db.create_all()
14     return '创建成功'
  • movie_view.py
1 from flask import Blueprint
2 
3 movie_blue = Blueprint("movie_blue",__name__,url_prefix="/movies/")
4 
5 @movie_blue.route('/')
6 def index():
7     return "Movie Index"

模型拆分

  选中model.py文件,右击选择Refactor选项,然后选择Convert To Python Package选项。

  将原来的model.py文件转换成一个包文件。再在这个包文件中去新建需要的model模型文件。

  • __init.py__
# 将各model文件导入到此文件中,作为对外的统一接口设置。
from .user_model import User
from .movie_model import Movie
  • user_model.py
1 from App.extension import db
2 
3 class User(db.Model):
4     id = db.Column(db.Integer,primary_key=True,autoincrement=True)
5     name = db.Column(db.String(32),unique=True)
6     password = db.Column(db.String(32))
  • movie_model.py
1 from App.extension import db
2 
3 class Movie(db.Model):
4     id = db.Column(db.Integer, primary_key=True, autoincrement=True)
5     m_name = db.Column(db.String(32))
6     m_detail = db.Column(db.String(32))

高级拆分方法 [推荐使用]

  此方法推荐使用。将每一个功能模块拆分一个包文件,然后再在这个包文件中进行路由视图函数、模型的逻辑书写。今后使用直接copy后,根据需求添加修改就可以

  day05_chaiAdvanced包文件中 是此项目的各种配置。以后想加什么功能模块,就在此文件同级目录创建包文件模块,然后在 工程 目录下的views.py文件中注册上就可以了。 

  

  第一块是 程序的入口,叫做:manage。

  第二块是 和工程名同名的一个包,里面有__init__.py文件、setting.py文件配置信息、extension.py文件负责扩展库、views.py文件负责路由注册

    __init__.py 文件中,有一个创建app设置,在程序入口manage内调用,

    __init__内 : 根据设置文件setting.py 加载配置;

          根据扩展库文件extension.py 初始化第三方扩展库;

          根据初始化路由文件views.py 进行加载路由

  第三块是 各个子模块。user包文件、movies包文件.........。各个子模块中又都有自己的 views.py文件和models.py文件

manage.py 文件中

 1 """ manage.py """
 2 
 3 import os
 4 
 5 from flask_migrate import MigrateCommand
 6 from flask_script import Manager
 7 from day05_chaiAdvanced import create_app
 8 
 9 # 从系统环境中获取参数FLASK_ENV的值给env,判断是什么环境下的服务器
10 # 避免外人修改代码,方便代码放在什么环境服务器下,就在什么环境下运行
11 # 在系统终端 vim .bashrc 编写系统环境变量:#FLASK_ENV。export FLASK_ENV = "develop" 保存退出
12 env = os.environ.get("FLASK_ENV") or 'default'
13 
14 # 首先创建一个flask对象、加载配置、加载扩展库、初始化路由
15 app = create_app(env)
16 # flask-scripy扩展
17 manager = Manager(app)
18 manager.add_command("db",MigrateCommand)
19 
20 if __name__ == '__main__':
21     manager.run()

day05_chaiAdvanced 包文件中

  • __init__.py
 1 ''' __init__.py '''
 2 from flask import Flask
 3 from day05_chaiAdvanced.settings import Config, envs
 4 from day05_chaiAdvanced.extension import init_ext
 5 from day05_chaiAdvanced.views import init_blue
 6 
 7 def create_app(env):
 8 
 9     # 创建Flask对象
10     app = Flask(__name__)
11 
12     # 加载初始化配置。 从类对象中加载。env参数确定在什么环境下的
13     app.config.from_object(envs.get(env))
14 
15     # 加载初始化扩展库。通过懒加载的方式加载(调用函数时参数的传递)
16     init_ext(app)
17 
18     # 加载初始化路由器。通过懒加载的方式加载(调用函数时参数的传递)
19     init_blue(app)
20 
21     return app
  • extension.py
 1 ''' extension.py '''
 2 from flask_sqlalchemy import SQLAlchemy
 3 from flask_migrate import Migrate
 4 
 5 db = SQLAlchemy()
 6 migate  = Migrate()
 7 
 8 # 通过写一个函数,使用函数传参数的形式将app传递过来。然后db利用app进行初始化
 9 def init_ext(app):
10     db.init_app(app) # db需要使用传过来的参数app来进行初始化
11     migate.init_app(app,db)
  • settings.py
 1 ''' settings.py '''
 2 # 对连接数据库的配置信息进行格式化整理
 3 def get_db_uri(dbinfo):
 4     database = dbinfo.get("DATABASE")
 5     driver = dbinfo.get("DRIVER")
 6     user = dbinfo.get("USER")
 7     password = dbinfo.get("PASSWORD")
 8     host = dbinfo.get("HOST")
 9     port = dbinfo.get("PORT")
10     name = dbinfo.get("NAME")
11     return "{}+{}://{}:{}@{}:{}/{}".format(database,driver,user,password,host,port,name)
12 
13 
14 # 配置信息初始化
15 class Config:
16     SECRET_KEY = 'asdfghjjkl'  # 随机值。系统可以基于一个密码随机生成随机值,这个值可以用来做密钥:
17     DEBUG = False
18     TESTING = False
19     SQLALCHEMY_TRACK_MODIFICATIONS = False
20 
21 
22 # 开发环境
23 class DevelopConfig(Config):
24     DEBUG = True
25     # 数据库信息配置
26     dbinfo = {
27         "DATABASE": "mysql",
28         "DRIVER":"pymysql",
29         "USER": "root",
30         "PASSWORD": "guoyapeng",
31         "HOST": "localhost",
32         "PORT": "3306",
33         "NAME": "FlaskModel",
34     }
35     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
36 # 测试环境
37 class TestingConfig(Config):
38     TESTING = True
39     # 数据库信息配置
40     dbinfo = {
41         "DATABASE": "mysql",
42         "DRIVER":"pymysql",
43         "USER": "root",
44         "PASSWORD": "guoyapeng",
45         "HOST": "localhost",
46         "PORT": "3306",
47         "NAME": "FlaskModel",
48     }
49     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
50 # 演示环境
51 class StagingConfig(Config):
52     # 数据库信息配置
53     dbinfo = {
54         "DATABASE": "mysql",
55         "DRIVER":"pymysql",
56         "USER": "root",
57         "PASSWORD": "guoyapeng",
58         "HOST": "localhost",
59         "PORT": "3306",
60         "NAME": "FlaskProject",
61     }
62     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
63 # 生产环境
64 class ProductConfig(Config):
65     # 数据库信息配置
66     dbinfo = {
67         "DATABASE": "mysql",
68         "DRIVER":"pymysql",
69         "USER": "root",
70         "PASSWORD": "guoyapeng",
71         "HOST": "localhost",
72         "PORT": "3306",
73         "NAME": "FlaskModelAdvanced",
74     }
75     SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)
76 
77 # 获取在什么环境下,不同环境下数据库不同
78 envs = {
79     "develop":  DevelopConfig,
80     "texting":  TestingConfig,
81     "staging":  StagingConfig,
82     "product":  ProductConfig,
83     "default":  ProductConfig,
84 }
85 
86 settings.py
settings.py
  • views.py
1 from movies.views import movie_blue
2 from users.views import user_blue
3 
4 # 创建的模块中的蓝图进行注册初始化
5 def init_blue(app):
6     app.register_blueprint(blueprint=user_blue)
7     app.register_blueprint(blueprint=movie_blue)

movies.py 包文件中

  • __init__.py  空
  • models.py
1 from day05_chaiAdvanced.extension import db
2 
3 
4 class Movie(db.Model):
5     id = db.Column(db.Integer, primary_key=True, autoincrement=True)
6     m_name = db.Column(db.String(32))
7     m_detail = db.Column(db.String(32))
  • views.py
1 from flask import Blueprint
2 from .models import Movie 
3 
4 movie_blue = Blueprint("movie_blue",__name__,url_prefix="/movies/")
5 
6 @movie_blue.route('/')
7 def index():
8     return "Movie Index"

users.py 包文件中 和movies.py 包文件类似。为了实现相应的功能的视图和模型的编写


 

转载于:https://www.cnblogs.com/TMMM/p/11479517.html

python之 flask 框架(1) flash 自定义转换器 jinja2 request WTForms 自定义验证器 上传文件 Flask-RESTful flask-sqlalchemy 一个数据库模型对应一个数据库中的表,所有的数据库模型都要基础ORM对象的Modle基类,即db.Model。 阅读详情

相关推荐

Flask蓝图:告别单文件泥潭,迈出模块化拆分

模块化开发的艺术 Flask蓝图是解决项目膨胀的利器,它通过模块化设计让代码保持优雅。本文从四个核心痛点切入,揭示了蓝图的价值: 代码组织 - 告别面条式代码,按业务垂直拆分 路由冲突 - 通过命名空间实现路径隔离 功能复用 - 独立模块可跨项目移植 统一前缀 - 轻松管理API版本和路由前缀 文章通过电商案例展示了蓝图的实际应用: 创建独立蓝图模块(如用户、商品) 构建工业级目录结构(API版本控制) 演示了URL前缀的三种配置方式 介绍嵌套蓝图等高级特性 最终呈现的是一套完整的Flask

数据知道的博客 736

Flask视图高级技术

第四章 Flask视图高级技术 目录 第四章 Flask视图高级技术 4.1 app.route与add_url_rule简介 4.2 Flask类视图 4.2.1标准类视图(不太理解) 4.2.2 基于方法的类视图 4.3 Flask装饰器 4.3.1装饰器的定义和基本使用 4.3.2 对带参数的函数使用装饰器 4.4蓝图 4.5 练习 1.请在路由中指定请求方法为GET和POST方法。 2.请用装饰器相关知识,编程实现统计一段程序中多个函数各自执行所花时间。 如何自己定义函数

武师叔的博客 1079

ArcGIS插值可视化气象数据

前言 地图底图的制作和气象数据的预处理见我上两篇博客 ArcGIS精美中国地图制作(详解) python处理日值气象数据 在前面我们已经将日值的地温数据处理成了年均地温,添加了站点经纬度坐标并导出为excel格式。 得到如下数据: 导入数据 在Arcmap中 文件-添加XY数据 将年均地温和站点位置数据导入。 注意:excel表格的格式要另存为97-2003工作簿形式,否则会有"arcgi...

江北20190411的博客 2万+

Python之Flask高级~钩子函数

效果如下,before_func函数会使用cache模块获取用户的ip,如果某个用户的IP请求太频繁会进行警告,若是初次访问则对该IP设置有效期,本次示例是1秒内限制访问,1秒后还是可以再次访问,没做其他复杂限制。钩子函数就是中间件,利用的编程思想就是AOP编程,也就是面向切面编程思想,比如在用户端以及在服务器端进行“切开”,设置钩子函数,通俗地讲就是两者之间设置一个函数组件进行某些操作达到比如反爬,防御攻击等的目的。(1)三个钩子函数中,最常用的是before_request,现直接上代码示范一下;

Smile_Lai的博客 1124

HALCON卡尺模型实战:5分钟搞定工件尺寸测量(附完整代码)

本文详细介绍了HALCON卡尺模型在工件尺寸测量中的实战应用,通过5分钟快速搭建测量系统的完整指南,包括基础配置、高级参数调优和完整代码示例。卡尺模型能自动识别边缘并计算精确尺寸,显著提升工业视觉检测的效率和一致性,特别适用于实时测量场景。

weixin_42570296的博客 462

STM32串口通信实战:从CubeMX配置到printf重定向全解析

串口通信是嵌入式系统中最基础且广泛使用的数据交换方式,它基于异步串行通信原理,通过TX(发送)和RX(接收)两根信号线实现设备间的全双工通信。其技术价值在于协议简单、硬件成本低、可靠性高,是单片机与上位机调试、传感器数据采集、设备控制等场景的首选方案。在STM32等ARM Cortex-M系列MCU中,USART外设通过硬件自动处理时序,大大减轻了CPU负担。本文聚焦于嵌入式竞赛与开发中的高频需求,以STM32G431RBT6为例,详解通过CubeMX配置USART1、实现按键触发数据发送、并完成print

weixin_30603633的博客 546

Python轻量级Web框架Flask(10)——Flask进阶知识(caching插件和Flask自带的钩子函数)

Flask插件可以去官网查看,有很多。插件安装流程:1、通过pip指令在对应环境中下载插件2、在项目的exts.py文件中初始化3、使用这个插件是一个和缓存相关的插件,缓存经常用来保留那些经常被访问的临时数据。

sz1125218970的博客 1567

LTSPICE仿真电路:(二十八)三极管厄利电压与输出特性曲线深度解析

本文深入解析了LTSPICE仿真电路中三极管的厄利电压与输出特性曲线,详细介绍了厄利电压的物理意义、仿真设置及实际应用。通过伏安特性曲线和厄利电压的分析,帮助读者理解三极管放大性能的关键参数,并提供了电路设计中的优化方案和故障排查技巧。

weixin_26899659的博客 149

Flask异常处理使用记录

Flask异常处理使用记录 初识Flask异常处理,是使用@app.teardown_request钩子函数错处理 # 遇到错误就执行 @app.teardown_request def teardown_request(e): print('error:', e) 我想搭配日志记录和错误状态返回 感谢该博主的文章 厉害厉害 我再改吧改吧, 哈哈 异常自定义 import json from flask import request from werkzeug.exception

憧憬001-的博客 511

18、AI在基础设施管理与运维中的应用及未来趋势

本文探讨了人工智能(AI)在基础设施管理和运维中的广泛应用,包括性能优化、成本节约、网络安全等多个场景。文章详细介绍了AI在不同领域的应用工具、实际案例以及面临的挑战,并展望了未来AI在基础设施管理中的发展趋势。此外,还分析了AI与Site Reliability Engineering(SRE)框架的结合优势,展示了AI如何提升运维效率和系统可靠性。

n7o8p的博客 148

2026年医疗AI的可信革命全栈实现(上)

医疗AI可信化:贝叶斯网络与向量数据库的协同架构 本文探讨2026年医疗AI发展的关键转折点——从追求生成能力转向构建可信决策系统。核心观点认为,医疗AI下一阶段的竞争焦点在于不确定性量化和错误传播约束,而非单纯的问答流畅度。研究提出以Python为开发语言、结合向量数据库与贝叶斯网络的混合架构: 技术分层 语言层(LLM):处理自然语言交互与工具调用 证据层(Milvus/Qdrant):实现可审计的临床知识检索 概率层(pgmpy/PyMC):执行贝叶斯推理与风险路由 治理层:确保权限控制与人工复核机制

AllenLV的博客 1151

python后端:Flask框架学习笔记

其实就是,如果我要访问一个数据,每天访问很多次,都是这个数据访问时##间又特别长,那么我们就加上这个cache,使得第一次加载的时候满,之后每一次加载直##接读缓存,节省时间,timeout=30是缓存的有效时间。g对象在一次请求中的所有的代码的地方,都是可以使用的突破变量存储位置限制, 为数据传递添加了新的方式, 比如我们在before_request产生一个数据在后面需要使用,可以保存在g对象中,在其他视图函数中就可以使用这个数据。所以我们要引入一个新概念,叫做蓝图blueprint。

qq_73099889的博客 2735

166、电流环带宽测试

本文分享了电流环带宽测试的实战经验,揭示了常见误区:误将系统其他环节(如PWM、ADC、传感器)的延迟当作电流环性能。强调带宽测试需先断开速度/位置环,采用扫频法注入正弦信号,结合伯德图分析幅值与相位响应。关键点包括:控制频率步进为对数、确保采样时序精准、避免传感器带宽限制影响结果。文中指出“假带宽”现象(如鼓包、增益超0dB)多源于非线性或机械共振,建议遵循“先开环后闭环”“带宽非越高越好”“阶跃验证”三原则,并建立出厂基准曲线以支持后期故障诊断。

2401_88858637的博客 177

Python-Flask 蓝图以及钩子函数(5)

Flask 蓝图一、初识蓝图的页面结构二、创建蓝图的步骤三、钩子函数 官方解释:Blueprint 是一种组织一组相关视图及其他代码的方式。与把视图及其他 代码直接注册到应用的方式不同,蓝图方式是把它们注册到蓝图,然后在工厂函数中 把蓝图注册到应用。 Flaskr 有两个蓝图,一个用于认证功能,另一个用于博客帖子管理。每个蓝图的代码 都在一个单独的模块中。使用博客首先需要认证,因此我们先写认证蓝图。 个人自己的理解:蓝图是路由的另一种方式,一个项目中会有很多不同的功能,如果将这些功能的视图写在一个app.p

肿肿的博客 1160

【AI理论学习】手把手推导扩散模型:Diffusion Models(DDPM)

生成扩散模型DDPM如下图所示分为前向、逆向两个过程,它首先通过不断往原始清晰数据中添加噪声使其变成标准高斯噪声(前向过程),而后期望从标准高斯噪声中还原原始数据(逆向过程)。若能实现,那便可从已知的标准高斯分布中采样一个噪声数据,而后利用DDPM模型生成符合原始数据分布的新数据。 Diffusion模型包含两个过程:数学符号:y∝xy\propto xy∝x:y正比于x,即y随着x增大而线性增大。 条件概率:贝叶斯公式:p(A∣B)=p(B∣A)×p(A)p(B)p(A|B)=\frac{p(B|A)\

小哲的博客 1511

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Flask笔记

filter可以用于非等值操作,而fliter_by只能等值操作。写一个controller(apis)一般使用Vue开发前后端分离项目。重新迁移一般不需要执行init。filter后可以继续过滤。一般的话都序列化成字符串。exts.py(放插件)删除views,不用蓝图。

qq_56127002的博客 1551

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

python web框架 flask(三)

flask(三) 一. request对象 浏览器带着用户的请求,经过flask框架创建出request对象,request对象包含当前用户的所以请求信息。 from flask import request request对象的属性: url:完整的url请求 base_url:去掉get传参的url host_url:只有主机地址和端口号 path:装饰中的路由地址 method:请求方法...

weixin_42563968的博客 254

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

python(68) Flask

Flask 是一个用 Python 编写的轻量级 Web 应用框架。安装 pip install Flask。

Python开发分享的博客 518

Python Web应用开发之Flask框架高级应用(三)——蓝图(Blueprints)

本文围绕 Flask 框架蓝图展开。在 Python Web 开发里,当应用规模变大,代码管理难度增加,蓝图成为优化利器。 文章开篇点明蓝图概念,它是 Flask 内的功能模块,可独立管理路由、视图等。接着阐述优势,能实现代码模块化、复用,助力团队协作。随后详细介绍蓝图从创建、定义路由到注册的全流程,还涉及属性方法与错误处理。旨在帮开发者掌握蓝图运用,通过合理划分功能模块,优化代码结构,提升开发效率与可维护性。

Smile的博客 1458

flask蓝图

蓝图 相当于django中的子应用,能够修改项目的目录结构,按需划分层次 在Flask中, 蓝图是一种用来扩展已有Flask应用结构的方式, 蓝图提供了一种把功能类似的视图函数组合在一起的方式, 通过这种方式, 开发者能够把他们的应用拆分成不同的组件. 在我们的架构中, 蓝图的作用类似于控制器. 蓝图的使用步骤分为三步: 1.创建一个蓝图对象 2.在这个蓝图对象上进行操作, 注册路由, 指定静态文件夹, 注册模板过滤器 3.在应用对象上注册蓝图对象 ...

weixin_69086891的博客 305

四、Flask 视图使用方法详细概述

1、请求上下文(Request Context):请求上下文是在处理每个请求时创建的,它包含了当前请求的相关信息,如请求头、请求参数、Cookies 等。Flask 使用线程局部变量来管理请求上下文,确保每个请求都拥有独立的上下文,并且不会混淆不同的请求。Flask 使用上下文管理技术来管理请求上下文和应用上下文,以便在处理请求和生成响应时能够访问到相关的上下文信息。当客户端发送请求时,Flask 的视图函数将根据路由规则匹配到对应的视图,并执行相应的逻辑来生成响应。这样可以避免在代码中硬编码 URL。

LKIDTI数据的博客 817

Flask学习笔记

写在前面1. Flask介绍2. Views3. Request4. Response5. 会话技术6. 模型和模板7. 数据传输加密反爬8. 钩子函数9. 用户激活、手机、邮箱10. Flask-RESTful11. 公司组成、项目架构12. 淘票票13. nginx14. logging 写在前面 学习链接:Python 900集(学完可就业/2019版):[359集: 451集],共93集 感想 | 摘抄 filter和filter_by区别 : 接收的参数类型不一样cls.query.fil

米不开朗基罗的博客 262

flask=======模板

一、flask-script扩展库 简介:一个终端运行解释器 通过在终端不同参数的启动来实现不同的功能的启动 安装 pip install flask-script 使用 ``` from flsak import Flask from flask_script import Manager app =Flask(__name__) manager =Manager...

小久IT之路 159

flask02

一、flask-script扩展库 简介: 一个终端运行的解析器 通过在终端不同参数的启动来实现不同功能的启动 django一样的启动发送 安装: pip3 install flask-script 使用 from flask import Flask from flask_script import Manager app = Flask(__name__) manager = Manager...

jokerBi的博客 225

Flask Blueprint 深度详解

Flask的Blueprint是一种代码组织工具,可将应用拆分为独立模块。它支持业务模块拆分(如用户管理、订单处理)、组件复用和团队协作。使用步骤包括创建Blueprint实例、编写视图函数、注册到主应用。最佳实践建议按功能划分目录、统一URL前缀命名、集中注册蓝图。相比Flask原生单文件应用,Blueprint更易于维护大型项目;与Django的App相比更轻量,与FastAPI的APIRouter功能类似但设计思路不同。Blueprint可与类视图结合使用,实现更清晰的代码结构。

leohu0723的博客 674
上一篇: flask 之(四) --- 扩展|缓存|会话
下一篇: flask 之(六) --- API|RestfulApi
baoding4359
博客等级 码龄11年 2粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值