Flask 模块化管理Blueprint基础版

蓝图 Blueprint

首先来瞅瞅 没有模块化的flask的简陋项目:

from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__,template_folder='templates')

# 配置
class Config(object):
    DEBUG = True
    SECRET_KEY = os.urandom(24)  # 随机生成一个密钥
    # 数据库链接配置 = 数据库名称://登录账号:登录密码@数据库主机IP:数据库访问端口/数据库名称?charset=编码类型
    SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1:3306/students?charset=utf8mb4"
    # 动态追踪修改设置,如未设置只会提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 查询时会显示原始SQL语句
    SQLALCHEMY_ECHO = True


app.config.from_object(Config)
# 初始化SQLAlchemy
db = SQLAlchemy()  # 初始化数据库操作对象
db.init_app(app)  # 初始化数据库链接


# models创建模型类
class yanilo(db.Model):
    # 表结构声明
    __tablename__ = "yanilo"

    # 字段声明
    id = db.Column(db.Integer, primary_key=True, comment="主键ID") # 字段类型
    name = db.Column(db.String(250), comment="姓名")
    age = db.Column(db.Integer, comment="年龄")
    sex = db.Column(db.Boolean, default=False, comment="性别")
    # DECIMAL设置小数精度,最多八位小数点后面两位 ,允许有空值,comment为列注释
    money = db.Column(db.DECIMAL(8,2), nullable=True, comment="钱包")

    def __repr__(self):          # 定义 __repr__ 是为了方便调试,你可以不定义,也可以定义的更详细一些。

        return self.name



# 路由+视图部分
@app.route('/')
def index():

    # qwq = yanilo(
    #     name='qwq',
    #     age=15,
    #     sex=True,
    #     money=1222,
    # )
    # db.session.add(qwq)
    # db.session.commit()
    a = yanilo.query.filter(yanilo.name=='qwq').first()
    print(a.sex,a.money,a.name,a.age)

    return 'ok'


if __name__ == '__main__':
    # with app.app_context():
        # db.create_all() # 根据模型创建所有的数据表
        # db.drop_all()   # 删除模型对应的所有数据表
    app.run()

模块化

随着flask程序越来越复杂,我们需要对程序进行模块化的处理,之前学习过python的模块化管理,于是针对一个简单的flask程序进行模块化处理

简单来说,Blueprint 是一个存储视图方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:

  • 一个项目可以具有多个Blueprint
  • 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名
  • 在一个应用中,一个模块可以注册多次
  • Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的
  • 在一个应用初始化时,就应该要注册需要使用的Blueprint

但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

Blueprint对象用起来和一个应用/Flask对象差不多,最大的区别在于一个 蓝图对象没有办法独立运行,必须将它注册到一个应用对象上才能生效

使用蓝图可以分为四个步骤

  1. 创建一个蓝图的包,例如users,并在__init__.py文件中创建蓝图对象
users=Blueprint('users',__name__)
  1. 在这个蓝图目录下, 创建views.py文件,保存当前蓝图使用的视图函数
@admin.route('/')
def home():
    return 'user.home'
  1. users/init.py中引入views.py中所有的视图函数
from flask import Blueprint
# 等同于原来在 manage.py里面的 app = Flask()
users=Blueprint('users',__name__)

from .views import *
  1. 在主应用main.py文件中的app对象上注册这个users蓝图对象
from users import users
app.register_blueprint(users,url_prefix='/users')

当这个应用启动后,通过/users/可以访问到蓝图中定义的视图函数

运行机制

  • 蓝图是保存了一组将来可以在应用对象上执行的操作,注册路由就是一种操作

  • 当在app对象上调用 route 装饰器注册路由时,这个操作将修改对象的url_map路由表

  • 然而,蓝图对象根本没有路由表,当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项

  • 当执行app对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身作为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的usr_map路由表

  • 蓝图的url前缀

  • 当我们在应用对象上注册一个蓝图时,可以指定一个url_prefix关键字参数(这个参数默认是/)
    在这里插入图片描述

  • 在应用最终的路由表 url_map中,在蓝图上注册的路由URL自动被加上了这个前缀,这个可以保证在多个蓝图中使用相同的URL规则而不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的自路径即可

  • url_for在使用时,如果要生成一个蓝图里面的视图对应的路由地址,则需要声明当前蓝图名称+视图名称

url_for('users.home') # /users/home

蓝图模块化基础版

└── qwq			# 项目文件名
    ├── database.py	  # SQLAlchemy初始化文件
    ├── __init__.py		
    ├── main.py			# 主文件 数据配置 创建flask对象 启动文件 main.py
    ├── templates		# 存放公共html的
    │   └── header.html
    └── users				#  存放子应用目录文件
        ├── __init__.py #  创建蓝图目录 并注册视图
        ├── models.py	# 定义模型类
        ├── users_static	# 存放子应用的静态文件 如css、js等
        │   └── 1.jpg
        ├── users_templates	# 存放子应用html的
        │   └── index.html
        └── views.py			# 视图

第一步:
在创建子应用包,users
在包下创建users_static、users_templates 文件夹 ,接着在包下创建modelsy.py、views.py

  1. 打开users包下的__init__.py,创建蓝图
    和应用对象不同,蓝图对象创建时不会默认注册静态目录的路由。需要我们在 创建时指定 static_folder 参数。
    下面的示例将蓝图所在目录下的static_users目录设置为静态目录

from flask import Blueprint
# 1. 创建蓝图目录并对蓝图对象进行初始化
user =Blueprint("users",__name__,template_folder="users_templates",
								static_folder='users_static',static_url_path="/libs")
# template_folder:自定义视图返回文件夹
# static_folder:  自定义静态资源返回文件夹
# static_url_path="/libs"  前端访问资源文件的前缀目录。  例:访问users_static下的图片
#  图片的路径: /users/libs/1.jpg   而不是/users/users_static/1.jpg
# 注:如果在 templates 中存在和 templates_users 有同名模板文件时, 则系统会优先使用 templates 中的文件
  1. 打开 views.py
from . import users
from flask import render_template
# @users.route('/')
# def home():
#     return 'user.home'

@users.route("/")
def index():
		# title 传递给index.html里的参数 
    return render_template("index.html",title="users/index/index.html") 
    

@users.route("/list")
def list():
    return "users/list"

    

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>蓝图下的模板</p>
    <h1>{{ title }}</h1>
    <p><img src="/users/libs/1.jpg" alt=""></p>
</body>
</html>
  1. 在打开包下的__init__.py,注册视图
# 1. 创建蓝图目录并对蓝图对象进行初始化
from flask import Blueprint
users=Blueprint('users',__name__,template_folder='users_templates',static_folder='users_static',static_url_path='/xxx')
# 3. 注册视图
from .views import *
  1. 打开users同级目录的mian,py
from flask import Flask
app = Flask(__name__)

class Config():
    # DEBUG调试模式
    DEBUG = True
    # json多字节转unicode编码
    JSON_AS_ASCII = False
    # 数据库链接配置
    # SQLALCHEMY_DATABASE_URI = "mysql://账号:密码@IP/数据库名?编码"
    SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1:3306/students?charset=utf8mb4"
    # 动态追踪修改设置,如未设置只会提示警告
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 查询时会显示原始SQL语句
    SQLALCHEMY_ECHO = True

app.config.from_object(Config)

from database import db
db.init_app(app)

# 4. 注册蓝图
from users import users     # 从users包下引入__init__里的users
from users.models import Yanilo  #  从users包下引入models里的Ynilo模型类 为在创建数据库表
app.register_blueprint(users,url_prefix="/users") # 把users注册到flask对象里 方便调用,设置访问子路由的主路由
if __name__ == '__main__':
    # with app.app_context():
    #     db.create_all()
    app.run()

database.py:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

models.py:

from database import db
class Yanilo(db.Model):
    __tablename__ = 'yanilo'
    id = db.Column(db.Integer,primary_key=True,comment='主键id')
    name = db.Column(db.String(250),comment='姓名')
    age = db.Column(db.Integer,comment='年龄')

    def __repr__(self):
        return self.name


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值