美文网首页
数据与Flask路由

数据与Flask路由

作者: 54小时50分 | 来源:发表于2018-08-14 17:43 被阅读0次

    3.1搜索而不是拍照上传

    鱼书网站是赠书的平台,所以不需要提供书的用户拍照和填写相关信息上传到平台。

    3.2 数据API

    数据不是来源于数据库,来源于API
    1、教程提供
    2、豆瓣网(格式略有不同)

    3.3搜索关键字

    @app.route('/book/search/<q><page>')
    def search(q,page):
        # q:普通关键字 isbn
        # page
    
        # isbn isbn13 13个0到9的数字组成
        # isbn10 10个0到9数字组成,含有一些‘_’
        isbn_or_key = 'key'
        if len(q) == 13 and q.isdigit():
            isbn_or_key = 'isbn'
        short_q = q.replace('_','')
        if '_' in q and len(short_q) == 10 and short_q.isdigit:
            isbn_or_key = 'isbn'
        pass
    

    3.4简单的重构

    所有的代码都到视图里是不合理的,我们新建一个helper.py,将isbn的函数移过去,这样函数代码就被封装起来

        # isbn isbn13 13个0到9的数字组成
        # isbn10 10个0到9数字组成,含有一些‘_’
    def is_isbn_or_key(word):
        isbn_or_key = 'key'
        if len(word) == 13 and q.isdigit():
            isbn_or_key = 'isbn'
        short_word = word.replace('_', '')
        if '_' in word and len(short_word) == 10 and short_word.isdigit:
            isbn_or_key = 'isbn'
        return isbn_or_key
    

    然后在fisher.py中引入该模块

    from helper import is_isbn_or_key
    

    引用这个判断函数

    def search(q,page):
        # q:普通关键字 isbn
        # page
    
        isbn_or_key = is_isbn_or_key(q)
    
        pass
    

    3.5 requests发送http请求及代码的简化手段

    新建HTTP.py

    class HTTP:
        def get(self):
            pass  
    

    使用repuests,先在命令行安装


    image

    (注,图片中pipenv 误输入成了pinenv)

    # urllib
    # requests
    
    from urllib import request
    import requests
    # http://t.yushu.im/v2/book/isbn/9787501524044
    
    class HTTP:
        def get(self,url,return_json=True):
            r = requests.get(url)
            # restful
            # json
            if r.status_code !=200:
                return {} if return_json else ''
            return r.json() if return_json else r.text
            # if r.status_code == 200:
            #     if return_json:
            #         return r.json()
            #     else:
            #         return r.text
            # else:
            #     if return_json:
            #         return {}
            #     else:
    

    1.简化if-else语句的几种方式 1.使用三元表达式 ;2.if+return;3.将if-else里的代码提取成函数
    2.if+return的理解:把最后一句return前的if+return 全都理解为正常流程之外的一种特例情况的处理;多次if-return,提前结束一些逻辑分支,可以提高代码思维的清晰性
    3.requests的一些说明:1.get()发送get请求;2.返回结果r.status_code 获取返回状态吗;3.r.json()将返回结果序列化成json;4.r.text 将返回结果不做处理直接返回

    3.6 requests vs urllib

    发送http请求的两种方法:
    1.使用urllib(python内置)
    2.使用requests(需要使用pip3安装)

    import requests
    # http://t.yushu.im/v2/book/isbn/9787501524044
    
    class HTTP:
        @staticmethod
        def get(url, return_json=True):
            r = requests.get(url)
            # restful
            # json
            if r.status_code != 200:
                return {} if return_json else ''
            return r.json() if return_json else r.text
    

    3.7 从API获取数据

    新建一个文件:yushu_book.py
    定义一个类,定义两个方法

    from http import HTTP
    
    class YuShuBook:
        isbn_url = 'http://t.yushu.im/v2/book/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 = HTTP.get(url)
            # dict
            return result
    
        @classmethod
        def search_by_keyword(cls, keyword, count=15,start=0):
            url = cls.keyword_url.format(keyword,count,start)
            result = HTTP.get(url)
            return result  
    

    3.8 使用jsonify

    fisher.py中,jsonnify的用法

    @app.route('/book/search/<q><page>')
    def search(q, page):
        # q:普通关键字 isbn
        # page
        # alt + enter ,将光标放在YuShuBook上,按alt + enter,
        # 然后选择YuShuBook所在yushu_book.py,会自动在本文件中from yushu_book import YuShuBook
    
        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)
            # dict 序列化
            # API
        return jsonify(result)
        # return json.dumps(result),200,{'content-type':'application/json'}
    

    3.9 将视图函数拆分到单独的文件中

    不能将所有的视图函数都放到一个文件中,比较好的做法是根据业务模块来分。
    入口文件fisher.py还是放到根目录下面,我们在根目录下建立一个子目录app,在app下面新建一个目录web,将视图函数分门别类的存放到web目录下面。
    首先在 web目录下新建一个文件book.py,将fisher.py中的视图函数移到book.py中,在book.py中导入相关引用文件。

    3.10 深入了解flask路由

    image

    flask的基本思想是内部会维护一个字典。每一个url都会对应一个视图函数,但是不仅仅是这样。每一个url还会对应一个endpoint端点。用于反向构建URL(后面会讲解)

    flask的路由注册app_url_rule(url=,view_func=,endpoint=)会接受三个参数,前两个我们都知道了,第三个就是上面说的endpoint。他的默认值是view_func的名称。当然,app.route('url',endpoint=)也可以传入

    3.11 循环引入流程分析

    fisher.py和book.py出现了循环引入的情况。下面看下fisher.py和book.py的具体流程图

    image

    图中有两种颜色的线:红色的线是fisher主执行文件被执行之后的执行路径;蓝色的线是book模块被导入之后循环导入的执行路径。
    1.主流程开始之后,首先到达导入book的语句。然后进入book模块中执行
    2.book模块开始之后,首先到达导入fisher的语句(循环导入),这个时候主流程暂时结束,重新执行fisher中的代码
    3.这时候又回到fisher中的导入book的语句,由于book已经被导入一次,所以不会再次导入,进入if语句,这个时候的name是book导入fisher时候的name:fisher,不是主流程main,所以if语句条件为false。蓝色线执行终止,重新回到2. book导入fisher的语句。
    4.继续向下执行book 中app.route注册路由的语句。然后book执行完,回到fisher主流程执行中。
    5.到达if语句,这个时候name为main。执行run方法,启动服务
    回答流程图中的两个问题:

    问题1:因为都是由fisher引入book,一个模块只会引入另一个模块一次。所以只执行了一次book
    问题2:由于一次是主流程执行fisher文件;一次是由book模块导入 fisher。

    3.12 找不到视图函数的最终解释与证明

    整个流程中,出现了两次核心app对象的初始化,注册路由是在蓝色流程中初始化的app注册的。但是启动服务是红色流程中的app启动的

    book中注册路由所使用的app对象,是他自己所导入fisher模块的app对象(蓝色流程中),而不是红色主流程中所实例化的app对象

    相关文章

      网友评论

          本文标题:数据与Flask路由

          本文链接:https://www.haomeiwen.com/subject/qmrnuftx.html