内容简介:在
修剪原始数据,获取真正需要的数据
在 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 来接收数据,然后分别判断 isbn 和 keyword ,进行调用类方法来获取数据,并且保存在 yushu_book 这个对象中,最后调用 books 这个对象的 fill 方法,来修剪得到的数据,返回我们需要的数据并且存在 books 这个对象中。整个过程还是挺抽象的。
如果你想返回一个json对象,那么你可以这样做
····· import json ····· return json.dumps(books,default=lambda o:o.__dict__) #将return jsonify(books)替换
以上所述就是小编给大家介绍的《「Flask实战」鱼书项目实战三》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 「Flask实战」鱼书项目实战一
- 「Flask实战」鱼书项目实战四
- 「Flask实战」鱼书项目实战六
- 「Flask实战」flask鱼书项目实战二
- go语言实战教程:Redis实战项目应用
- Runtime项目实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Black Box Society
Frank Pasquale / Harvard University Press / 2015-1-5 / USD 35.00
Every day, corporations are connecting the dots about our personal behavior—silently scrutinizing clues left behind by our work habits and Internet use. The data compiled and portraits created are inc......一起来看看 《The Black Box Society》 这本书的介绍吧!