「Flask实战」flask鱼书项目实战二

flask-python

flask鱼书项目实战


单蓝图多模块拆分视图函数

上一篇后成功将蓝图注册到app上,但是有一个问题是要实现的是单蓝图多模块拆分视图函数,这样肯定是不行的,所以我们将蓝图注册到web下的__init__.py下,然后将之前的book导入,这样以后有新的模块,只需要在__init__下导入就可以注册到web这个蓝图下了

from flask import Blueprint

web = Blueprint('web', __name__)

from app.web import book

修改book.py内容

from flask import jsonify
from . import web

from helper import is_isbn_or_key
from yushu_book import YuShuBook


@web.route('/book/search/<q>/<page>')
def search(q,page):
    isbn_or_key = is_isbn_or_key(q)
    if isbn_or_key == 'isbn':
        result = YuShuBook.search_by_isbn(q)
    else:
        result = YuShuBook.search_by_keyword(q)
    return jsonify(result)

将q和page作为get请求传参

├── app
│    ├──forms
│    │    └── BookForm.py
│    ├── web
│    │    ├── __init_.py
│    │    ├── book.py
│    │    ├── setting.py
│    │    └── secure.py
│    └── __init__.py
├── static 
├── templates
├── fisher.py
├── helper.py
├── HttpRequest.py
├── YuShu_Book.py

首先我们新建两个配置文件setting.pysecure.py
setting用于存放一般的配置,如后面用到的PRE_PAGE
secure用于存放机密配置,如数据库信息等
forms文件夹用于存放所有表单验证模块
secure.py,setting.py注册到app

#app/__init__.py
from flask import Flask
from app.models.sql_book import db

def create_app():
    app = Flask(__name__)
    app.config.from_object('app.secure')
    app.config.from_object('app.setting')
    register_blueprint(app)
    return app

def register_blueprint(app):
    from app.web import web
    app.register_blueprint(web)

form get参数验证

#BookForm.py
from wtforms import Form,StringField,IntegerField
from wtforms.validators import Length, NumberRange,DataRequired


class SearchForm(Form):
    q = StringField(validators=[Length(min=1,max=30),DataRequired()])
    #DataRequired()方法要求用户必须输入,且不能为空格
    page = IntegerField(validators=[NumberRange(min=1,max=99)],default=1)
    #设置了page的默认值,如果不穿page参数,则取1

将验证模块导入book模块中,并且讲拼接到路径中的pageq都改成get请求方式

from flask import jsonify,request
from . import web

from app.forms.BookForm import SearchForm
from helper import is_isbn_or_key
from yushu_book import YuShuBook


@web.route('/book/search')
def search():
    form = SearchForm(request.args)
    if form.validate():  #使用验证其验证
        q = form.q.data.strip()
        page = form.page.data
        isbn_or_key = is_isbn_or_key(q)
        if isbn_or_key == 'isbn':
            result = YuShuBook.search_by_isbn(q)
        else:
            result = YuShuBook.search_by_keyword(q,page)  #这里添加了page参数
            print(q)
        return jsonify(result)
    else:     #flask种每个条件下必须有返回否则会报错
        return jsonify({'msg':'参数校验失败'})

重构yushu_book.py

from HttpRequest import HTTP
from flask import current_app

class YuShuBook:
    isbn_url = 'http://t.yushu.im/v2/book/isbn/{}'
    keyword_url = 'http://t.yushu.im/v2/book/search?q={}&start={}&count={}'

    @classmethod
    def search_by_isbn(cls,isbn):
        url = cls.isbn_url.format(isbn)
        result = HTTP.get(url)
        return result

    @classmethod
    def search_by_keyword(cls,keyword,page=1):
        url = cls.keyword_url.format(keyword,cls.get_start_page(page),current_app.config['PRE_PAGE'])
        result = HTTP.get(url)
        return result

    @staticmethod
    def get_start_page(page):
        return (page-1) * current_app.config['PRE_PAGE'] #从第0页开始

到此就可以完成基本的isbn请求获取数据和关键字请求获取参数

测试

isbn:http://127.0.0.1:5000/book/search?q=9787501524044
「Flask实战」flask鱼书项目实战二 Python 第2张
keyword:http://127.0.0.1:5000/book/search?q=郭敬明
「Flask实战」flask鱼书项目实战二 Python 第3张

模块分类

app文件夹下创建三个新的文件夹spider,modelslibs
将对应的模块放入相应的文件夹下,新目录结构如下

├── app
│    ├──forms
│    │    └── BookForm.py
│    ├── web
│    │    ├── __init_.py
│    │    ├── book.py
│    │    ├── setting.py
│    │    └── secure.py
│    ├──libs
│    │    ├── helper.py
│    │    └── HttpRequest.py
│    ├──spider
│    │    └── yushu_book.py
│    ├──models
│    │    └── sql_book.py
│    └── __init__.py
├── static 
├── templates
├── fisher.py

数据库操作

sql_book.py下创建数据库模型

from sqlalchemy import Column,Integer,String
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


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))

secure.py下添加数据库连接配置

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/fisher'
SQLALCHEMY_TRACK_MODIFICATIONS = True

然后将 db注册到app

#app/__init__.py
from flask import Flask
from app.models.sql_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.init_app(app)
    db.create_all(app=app)
    return app

def register_blueprint(app):
    from app.web import web
    app.register_blueprint(web)

执行app后就可以在fisher中看到book

参与评论