
app核心对象 ,在这个核心对象上可以插入很多蓝图,这个蓝图是不能单独存在的,必须将app作为插板插入app ,在每一个蓝图上,可以注册很多静态文件,视图函数,模板 ,一个业务模块可以做为一个蓝图,比如book,之前的book.py 放到了app/web/路径下,就是考虑到了蓝图,app属于是整个Flask应用层,web属于是蓝图__init__文件中,比如Flask的核心应用app初始化对象,应该放入到在应用层级app包的 __init__.py 中 ,而蓝图的初始化应该放入到蓝图层的web包__init__.py中,如图:

app/__init__.py# -*- coding: utf-8 -*-
from flask import Flask
def create_app():
app = Flask(__name__)
app.config.from_object('config')
# 要返回回去
return app# -*- coding: utf-8 -*-
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=app.config['DEBUG'])app/web/book.py中,记得导入Blueprint# -*- coding: utf-8 -*-
from flask import jsonify, Blueprint
from helper import is_isbn_key
from ShanqiuBook import ShanqiuBook
# 蓝图 blueprint,进行初始化,蓝图的名字和参数为蓝图所在的模块名一般用__name__
web = Blueprint ('web',__name__)
# 此时这里用的就是web了
@web.route('/book/search/<q>/<page>')
def hello(q,page):
is_or_key = is_isbn_key(q)
if is_or_key == 'isbn':
result = ShanqiuBook.search_by_isbn(q)
else:
result = ShanqiuBook.search_by_keyword(q)
return jsonify(result)app/__init__.py # -*- coding: utf-8 -*-
from flask import Flask
def create_app():
app = Flask(__name__)
app.config.from_object('config')
# 调用一下就可以
register_blueprint(app)
return app
# 通过这个方法插入到app中
def register_blueprint(app):
from app.web.book import web
# 注册这个蓝图对象
app.register_blueprint(web)# -*- coding: utf-8 -*-
from flask import jsonify, Blueprint
from helper import is_isbn_key
from ShanqiuBook import ShanqiuBook
# 导入web模块
from . import web
@web.route('/book/search/<q>/<page>')
def hello(q,page):
# 调用方法判断用户是根据什么查的
is_or_key = is_isbn_key(q)
if is_or_key == 'isbn':
result = ShanqiuBook.search_by_isbn(q)
else:
result = ShanqiuBook.search_by_keyword(q)
return jsonify(result)# -*- coding: utf-8 -*-
# 导入web模块
from . import web
@web.route("/user/login")
def login():
return "success"app/web/__init__.py文件中,定义这个蓝图对象# -*- coding: utf-8 -*-
# 蓝图 blueprint,进行初始化
from flask import Blueprint
web = Blueprint ('web',__name__)
# 这两个导入之后就可以成功的运行对应模块中相关的代码,注意这个位置,这蓝图实例化之后
from app.web import book
from app.web import user/book/search/<q>/<page>这种格式的,Flask会将<>里的值自动映射成视图函数方法的参数,但是这种格式用着不爽,要把用户输入的参数作为请求参数传入,这个时候就要使用这种格式了http://127.0.0.1:5000/book/search/?q=金庸&page=1 # -*- coding: utf-8 -*-
# 导入这个request模块,
from flask import jsonify, Blueprint,request
from helper import is_isbn_key
from ShanqiuBook import ShanqiuBook
from . import web
# http://127.0.0.1:5000/book/search/?q=金庸&page=1
@web.route('/book/search/')
def hello():
# 通过Request对象拿到对应值的信息,但是这个并不是py中原始的字典,而是dict的子类immutableDict
q = request.args['q']
page = request.args['page']
# ip = request.remote_addr
# 通过这个方法把它转换为普通的dict
# a = request.args.to_dict()
# print(a)
is_or_key = is_isbn_key(q)
if is_or_key == 'isbn':
result = ShanqiuBook.search_by_isbn(q)
else:
result = ShanqiuBook.search_by_keyword(q)
return jsonify(result)(flask--yQglGu4) E:\py\qiyue\flask>pipenv install wtforms # -*- coding: utf-8 -*-
# 导入需要使用的模块
from wtforms import Form,StringField,IntegerField
from wtforms.validators import Length,NumberRange
class SearchForm(Form):
# 直接调用内置对象
# 参数校验规则:
# 1.定义的属性名q,page要与要校验的参数同名
# 2.根据要传入的参数类型选择不同的Field类进行实例化
# 3.传入一个数组,作为校验规则validators
# 4.可以设置默认值
q = StringField(validators=[DataRequired(),Length(min=1,max=30)])
page = IntegerField(validators=[NumberRange(min=1,max=10)],default=1)# -*- coding: utf-8 -*-
from flask import jsonify, Blueprint,request
from helper import is_isbn_key
from ShanqiuBook import ShanqiuBook
from . import web
# 导入参数校验
from app.forms.book import SearchForm
# http://127.0.0.1:5000/book/search/?q=金庸&page=1
@web.route('/book/search/')
def hello():
# 验证层
# 实例化我们自定义的SearchForm,需要传入一个字典作为要校验的参数
form = SearchForm(request.args)
# validate()方法返回True/False来标示是否校验通过
if form.validate():
# 从form中取出校验后的q与page,并且清除空格
q = form.q.data.strip()
page = form.page.data
is_or_key = is_isbn_key(q)
if is_or_key == 'isbn':
result = ShanqiuBook.search_by_isbn(q)
else:
result = ShanqiuBook.search_by_keyword(q)
return jsonify(result)
else:
return jsonify({'msg':'参数校验失败'}) @classmethod
def search_by_key(cls, q, count=15, start=0):
# count:每页显示的数量
# start:每页的第一条数据的下标
url = cls.search_by_key_url.format(q, count, start)
return HTTP.get(url)ShanqiuBook.py -*- coding: utf-8 -*-
from httper import httper
# 通过这种方式来导入当前的app对象,方便调用配置而文件
from flask import current_app
class ShanqiuBook:
isbn_url = 'http://t.yushu.im/v2/book/search/isbn/{}'
keyword_url = 'http://t.yushu.im/v2/book/search?q={}&count={}&start={}'
@classmethod
def search_by_isbn(cls,isbn):
url = cls.isbn_url.format(isbn)
result = httper.get(url)
return result
@classmethod
def search_by_keyword(cls,keyword,page=1):
# 每页显示的数据(通过这种方式从配置文件中获取到),每一页的起始下标
url = cls.keyword_url.format(keyword,current_app.config['PER_PAGE'],cls.calculate_start(page))
result = httper.get(url)
return result
# 获取每一页的起始下标
@staticmethod
def calculate_start(page):
return (page -1 ) * current_app.config['PER_PAGE']app/__init__.py文件中把配置文件添加到app中#-- coding: utf-8 --
from flask import Flask
def create_app():
app = Flask(name)
# app.config.from_object('config')
# 把配置文件装载进来
app.config.from_object('app.secure')
app.config.from_object('app.setting')
register_blueprint(app)
return app
def register_blueprint(app):
from app.web.book import web
app.register_blueprint(web)

(flask--yQglGu4) E:\py\qiyue\flask>pipenv install flask-sqlalchemy# -*- coding: utf-8 -*-
# 首先导入
from sqlalchemy import Column,Integer,String
# sqlalchemy,自动化映射
# Flask_SQLAlchemy,这个是Flask封装后的api,更加人性化
class Book():
# 需要把这些属性的默认值写成sqlalchemy提供的固定的类型
# Column()传入参数:数据类型,主键,自增
id = Column(Integer,primary_key=True,autoincrement=True)
# 数据类型,不为空
title = Column(String(50),nullable=False)
author = Column(String(30),default='未名')
binding = Column(String(20))
publisher = Column(String(50))
price = Column(String(20))
pages = Column(Integer)
pubdate = Column(String(20))
# 唯一:unique=True
isbn = Column(String(15),nullable=False,unique=True)
summary = Column(String(1000))
image = Column(String(50))
# 定义一些方法
def sample(self):
pass# -*- coding: utf-8 -*-
from sqlalchemy import Column,Integer,String
# 将模型映射到数据库中
# 首先导入核心的对象
from flask_sqlalchemy import SQLAlchemy
# 初始化
db = SQLAlchemy()
# 继承db.Model
class Book(db.Model):
id = Column(Integer,primary_key=True,autoincrement=True)
title = Column(String(50),nullable=False)
author = Column(String(30),default='未名')
binding = Column(String(20))
publisher = Column(String(50))
price = Column(String(20))
pages = Column(Integer)
pubdate = Column(String(20))
isbn = Column(String(15),nullable=False,unique=True)
summary = Column(String(1000))
image = Column(String(50))app/__init__.py中进行模型与flask关联# -*- coding: utf-8 -*-
from flask import Flask
# 导入这个db
from app.models.book import db
def create_app():
app = Flask(__name__)
app.config.from_object('app.secure')
app.config.from_object('app.setting')
register_blueprint(app)
# 把这个db和核心对象关联起来了
db.init_app(app)
# 注意这里,这样写的话会报错
db.create_all() # 把所有的数据模型映射到数据库中
return app
def register_blueprint(app):
from app.web.book import web
app.register_blueprint(web)# -*- coding: utf-8 -*-
# 存放比较机密的配置文件
DEBUG = True
# 数据库连接url,固定格式
# 要连接的数据库类型,数据库驱动(这里还要进行安装:pipenv install cymysql)
SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://root:123456@localhost:3306/book' 'No application found. Either work inside a view function or push'这个是因为在Flask中,不是实例化了app核心对象,其他代码就可以直接使用,要在上面的第二步的注意事项中` db.create_all()`方法中,把app核心对象传入即可db.create_all(app=app),这样就可以了,在数据库中就可以看到表了
