「Flask实战」鱼书项目实战三

栏目: Python · 发布时间: 5年前

内容简介:在

「Flask实战」鱼书项目实战三

flask 鱼书 项目 实战

修剪原始数据,获取真正需要的数据

app 下新建一个 view_modles 文件夹,用来存放 view modle ,然后新建一个 book.py 文件处理从 yushu_book.py 中获取的原始数据。因为在网页中,需要获取 作者搜索关键字 等信息,而从鱼书api中获取的信息有所不同,所以这个 view modle 就是用来处理这些原始数据,把他转化成我们需要的数据结构的模块。

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

class BookViewModle:
    @classmethod
    def package_single(cls,data,keyword):
        returned = {
            'books':[],
            'total':0,
            'keyword':keyword,
        }

        if data:
            returned['total']= 1
            returned['books']= [cls.__cut_book_data(data)]
        return returned

    @classmethod
    def package_collection(cls,data,keyword):
        returned = {
            'books': [],
            'total': 0,
            'keyword': keyword,
        }

        if data:
            returned['total'] = data['total']
            returned['books'] = [cls.__cut_book_data(book) for book in data['books'] ]
            # 运用列表推导式简化代码量
        return returned

    @classmethod
    def __cut_book_data(cls,data):
        book = {
            'title':data['title'],
            'publisher':data['publisher'],
            'pages':data['pages'] or '',   # 这里当pages的值是null的时候返回空,有利于后期模板渲染
            'price':data['price'] or '',
            'author':'、'.join(data['author']), # 通过join方法快速拼接作者
            'summary':data['summary'] or '',
            'image':data['image'],
        }
        return book

然后在 web/book.py 接收修剪后的数据。

# web/book.py

·····
from app.view_models.book import BookViewModle

·····

if isbn_or_key == 'isbn':
    result = YuShuBook.search_by_isbn(q)
    result = BookViewModle.package_single(result,q)
else:
    result = YuShuBook.search_by_keyword(q,page)
    result = BookViewModle.package_collection(result,q)

·····

然后就可以看到修剪后的数据效果了。

推倒前面的伪面向对象

发现面向对象中绝大多数都是 @classmethod ,如果面向对象中出现大量可以被作为 @classmethod 的方法,就可以说他是一个伪面向对象,不是用面向对象的思想构建的。例如 yushu_book.py 下的 YuShuBook 类,之所以出现这种问题是因为这个类自身并不会去保存数据,而是把所有数据都返回给了调用方,只是包装了一系列方法,去除了这个类名,他依然可以调用,所以应该把这些类的特征保存在这个类中,而不是返回给调用方。所以重构一下 YuShuBook

#spider/yushu_book.py
from app.libs.HttpRequest import HTTP
from <a href="https://www.miaoroom.com/tag/flask" data-toggle="tooltip" title="查看更多关于 flask 的文章" target="_blank">flask</a> 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={}'

    def __init__(self):
        self.total = 0
        self.books = []

    def search_by_isbn(self,isbn):
        url = self.isbn_url.format(isbn)
        # 如果中没有这个属性就会从类属性中去找
        result = HTTP.get(url)
        self.__file_single(result)

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

    def __file_single(self,data):
        if data:
            self.total = 1
            self.books.append(data)

    def __file_conllection(self,data):
        if data:
            self.total = data['totak']
            self.books = data['books']

    def get_start_page(page):
        return (page-1) * current_app.config['PRE_PAGE']

推倒整个 BookViewModle ,重写 view_modles 下的 book.py

# view_modles/book.py
class BookViewModle:
    def __init__(self,book):
        self.title = book['title']
        self.title = book['title']
        self.publisher= book['publisher']
        self.pages= book['pages']
        self.price = book['price']
        self.author = '、'.join(book['author'])
        self.summary = book['summary']
        self.image= book['image']

class BookCollection:
    def __init__(self):
        self.total = 0
        self.books =[]
        self.keyword = ''

    def fill(self, yushu_book, keyword):
        self.total = yushu_book.total
        self.keyword = keyword
        self.books = [BookViewModle() for book in yushu_book.books]

重写主视图函数下的 serach 视图函数

#web/book.py
@web.route('/book/search')

·····
from app.view_models.book import BookViewModle
from app.view_models.book import BookCollection
·····

def search():
    form = SearchForm(request.args)
    books = BookCollection()
    if form.validate():
        q = form.q.data.strip()
        page = form.page.data
        isbn_or_key = is_isbn_or_key(q)
        yushu_book = YuShuBook()
        if isbn_or_key == 'isbn':
            yushu_book.search_by_isbn(q)
        else:
            yushu_book.search_by_keyword(q,page)
        books.fill(yushu_book,q)
        return jsonify(books)
        #注意这个时候在查询是得不到数据的,因为这时候是一个对象实例,python不能把一个实例  序列化,因为之后的模板渲染不需要json所以这里不需要继续操作
    else: 
        return jsonify(form.errors) 
        #这里不采用自定义的错误了,直接返回表单验证的错误信息

理解一下这个顺序,首先把 BookCollection 实例化,然后如果表单验证通过,实例化 YuShuBook 来接收数据,然后分别判断 isbnkeyword ,进行调用类方法来获取数据,并且保存在 yushu_book 这个对象中,最后调用 books 这个对象的 fill 方法,来修剪得到的数据,返回我们需要的数据并且存在 books 这个对象中。整个过程还是挺抽象的。

如果你想返回一个json对象,那么你可以这样做

·····

import json

·····
return json.dumps(books,default=lambda o:o.__dict__)
#将return  jsonify(books)替换

以上所述就是小编给大家介绍的《「Flask实战」鱼书项目实战三》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Linux内核设计的艺术

Linux内核设计的艺术

新设计团队 / 机械工业出版社华章公司 / 2011-6-20 / 79.00元

关于Linux内核的书已经不计其数,但这本书却是独树一帜的,它的内容代表着Linux内核研究成果的世界顶尖级水平,它在世界范围内首次提出并阐述了操作系统设计的核心指导思想——主奴机制,这是所有操作系统研究者的一笔宝贵财富。本书可能也代表着同类图书的顶尖水平,是一本真正能引导我们较为容易地、极为透彻地理解Linux内核的经典之作,也可能是当前唯一能从本质上指引我们去设计和开发拥有自主知识产权的操作系......一起来看看 《Linux内核设计的艺术》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具