内容简介:在
修剪原始数据,获取真正需要的数据
在 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项目实战
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript实战手册
David Sawyer McFarland / 李强 / 机械工业出版社 / 2009 / 89.00元
在《JavaScript实战手册》中,畅销书作者David McFarland教你如何以高级的方式使用JavaScript,即便你只有很少或者没有编程经验。一旦掌握了这种语言的结构和术语,你将学习如何使用高级的JavaScript工具来快速为站点添加有用的交互,而不是一切从头开始编写脚本。和其他的Missing Manuals图书不同,《JavaScript实战手册》清楚、精炼,手把手地讲解。 ......一起来看看 《JavaScript实战手册》 这本书的介绍吧!