• flask(一)之路由和视图


     01-介绍

     Flask 是一个 Python 实现的 Web 开发微框架,同时具有很强的扩展能力。

    02-第一个flask程序

    # 初始化
    
    from flask import Flask, url_for, views
    app = Flask(__name__)

    Flask类的构造函数只有一个必须指定的参数,即应用主模块或包的名称。在大多数应用中,Python的__name__变量就是所需的值。

    from flask import Flask
    
    # 创建flask对象,传递__name__参数进去
    app = Flask(__name__)
    
    
    # url与视图映射
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run()  # 也可以更改端口号 run(port=5500)

    03-设置debug模式

    from flask import Flask
    import config
    #创建一个Flask对象,传递__name__参数进去
    app = Flask(__name__)
    # app.debug = True   #第二种
    # app.config.update(DEBUG=True)  #第三种
    app.config.from_object(config)   #第四种
    
    #url与视图映射
    @app.route('/')
    def hello_world():
        print('helloworkl')
        return 'Hello World!'
    
    if __name__ == '__main__':
        # app.run(debug=True)   #第一种
        app.run()

    04-配置文件

     新建config.py

    DEBUG =True

    主程序中的两种引用方式:

    # 第一种:推荐使用
    import config
    app.config.from_object(config)  
    
    # 第二种:
    app.config.from_pyfile('config.py')

    05-url传参方式

    from flask import Flask, request
    
    # 创建flask对象,传递__name__参数进去
    app = Flask(__name__)
    
    
    # 普通的传参方式  127.0.0.1:5000/p/1
    @app.route('/p/<id>/')
    def article_detail(id):
        return '你访问的文章第%s篇' % id
    
    
    """
    指定参数类型
    有以下几种类型:
        string:默认的数据类型
        int:接受整形
        float:浮点型
        path:和string的类似,但是接受斜杠
        any:可以指定多个路径
        uuid:只接受uuid字符串
    """
    
    
    # any:  127.0.0.1:5000/blog/id  127.0.0.1:5000/user/id
    @app.route('/<any(blog,user):url_path>/<id>')
    def detail(url_path, id):
        if url_path == 'blog':
            return '博客详情%s' % id
        else:
            return '用户详情%s' % id
    
    
    # path:  127.0.0.1:5000/article/python/1/
    @app.route('/article/<path:test>/')
    def test_article(test):
        return 'test_article:{}'.format(test)
    
    
    # 获取参数  127.0.0.1:5000/tieba/?wd=python
    @app.route('/tieba/')
    def tieba():
        wd = request.args.get('wd')
        return '获取的参数的是%s' % wd
    
    
    if __name__ == '__main__':
        app.run()

    06-url_for:实现创建url,只是生成一个url

    如果要生成一个css样式的静态文件的url需要使用url_for('static',filename='style.css')来创建相应的url。

    视图中的url_for:

    # 1. 通过视图函数解析出url
    
    from flask import Flask, url_for
    
    @app.route('/')
    def hello_world():
        # url_for里面:第一个是视图函数,第二个是url需要的参数
        return url_for('my_list',page=2)   
    
    @app.route('/list/<page>/')
    def my_list(page):
        return 'my_list'
    
    访问 127.0.0.1:5000/,结果:/list/2/
    
    # 2. url_for里面多的参数会当做搜索字符
    
    @app.route('/')
    def hello_world():
        return url_for('my_list',page=2,count=2)   
    
    @app.route('/list/<page>/')
    def my_list(page):
        return 'my_list'
    
    访问 127.0.0.1:5000/,结果:/list/2/?count=2

    模板中的url_for:

    模板中的url_for和视图函数中的url_for是类似的,也是传递视图函数的名字,也可以传递参数。使用的时候,需要在url_for两边加上一个{{ url_for('func_name'),ref='/',id='1'}}

    07-Response

    视图函数中可以返回的类型:
        1. 可以返回字符串,返回的字符串其实底层将这个字符串包装成了一个‘Response’对象
        2. 可以返回元组,形式(响应体,状态码,头部信息),返回的元组其实底层将这个字符串包装成了一个‘Response’对象
        3. 可以返回Response及其子类
    
    实现一个自定义的Response对象:
        1.继承自、‘Response’类
        2. 实现方法‘force_type’
        3. 指定‘app.response_class’为你自定义的‘Response’对象
        4. 如果视图函数返回的数据,不是字符串,也不是元组,也不是Response对象,那么就会将返回值传给‘force_type’,然后将‘force_type’的返回值返回给前端
    from flask import Flask,url_for,Response,jsonify
    
    app = Flask(__name__)
    
    class JsonResponse(Response):
    
        @classmethod
        def force_type(cls, response, environ=None):
            '''
            这个方法只有视图函数返回非字符、非元祖、非Response对象才会调用
            :param response:
            :param environ:
            :return:
            '''
            # 把字典转换成json
            if isinstance(response,dict):
                # jsonify将字典转换成json对象,还将该对象包装成了一个Response对象
                response = jsonify(response)
            return super(JsonResponse, cls).force_type(response,environ)
    
    app.response_class = JsonResponse
    
    
    @app.route('/')
    def hello_world():
        return 'Hello world'
    
    @app.route('/list1/')
    def list1():
        return Response('list1')  # 合法对象,直接返回
    
    @app.route('/list3/')
    def list3():
        return {'username':'derek','age':18}   # 返回的是非字符、非元祖、非Response对象,所以执行force_type方法
    
    if __name__ == '__main__':
    
        app.run(debug=True)

    08-add_url_rule:

    from flask import Flask, render_template, url_for
    
    app = Flask(__name__)
    app.config.update({
        'DEBUG':True,
       # 配置自动加载模板文件,调试模式下会自动开启
    'TEMPLATES_AUTO_RELOAD':True }) @app.route('/',endpoint='index') def hello_world(): print(url_for("derek_list")) # 通过endpoint找到对应的url /list/ return render_template('index.html') def my_list(): return "列表页" # 三个参数 # 1.url # 2.给url起个别名,如果没有指定endpoint,则默认使用视图函数的名字作为endpoint的值 # 3.视图函数 app.add_url_rule('/list/',endpoint='derek_list',view_func=my_list) with app.test_request_context(): print(url_for('index')) # / if __name__ == '__main__': app.run()

    09-render_template: 渲染模板文件

    from flask import Flask, render_template, url_for
    
    return render_template('index.html')

    10-send_from_directory:主要用于下载文件

    from flask import Flask
    from flask import g
    from flask import send_from_directory
    from flask import url_for
    import os.path
     
    app = Flask(__name__)
    dirpath = os.path.join(app.root_path,'upload')
    @app.route("/download/<path:filename>")
    def downloader(filename):
        return send_from_directory(dirpath,filename,as_attachment=True)

     11-static_url_path和static_folder

     static_url_path主要用于改变url的path的,静态文件放在static下面,所以正常情况url是static/filename ,但是可以通过static_url_path来改变这个url。

     static_folder主要是用来改变url的目录的,默认是static,可以通过这个变量来改变静态文件目录。

    from flask import Flask
    from flask import g
    from flask import send_from_directory
    from flask import url_for
    import os.path
     
    app = Flask(__name__,static_url_path="/test")
     
    @app.route("/")
    def static_create():
        return url_for('static',filename='style.css')

    12-Request对象

    Request是Flask中表示当前请求的request对象,一般称之为请求上下文变量(可以理解成全局变量,在任意一个视图中都可以访问到)。常用的属性有:
    
      args:url中的查询字符串。本质上是键值对,跟在"?"后面,多个键值对之间使用"&"连接;
    
      form:请求url中的表单数据。也是由键值对组成,一般使用post方法提交数据
    
      cookies:请求中的cookie信息。由服务器生成的键值对,把值发送给客户端并保存,稍后重点讲解!
    
      files:上传的文件

    12-类视图

    1. 继承views.VIew。
    2. 必须实现‘dispatch_request’方法,以后请求过来后,都会执行这个方法,返回值相当于视图函数一样,必须返回'Response'或者子类的对象,或者是字符串,或者是元祖。
    3. 必须通过app.add_url_role(url_rule,view_func)来做url与视图的映射。
    from flask import Flask, url_for, views
    # 创建一个Flask对象,传递__name__参数进去
    app = Flask(__name__)
    
    app.config.update({
        'DEBUG': True,
        'TEMPLATES_AUTO_RELOAD': True,
    })
    
    
    class ListView(views.View):
        def dispatch_request(self):
            return "我的列表页"
    
    
    # 1.ListView.as_view('list')里面必须传个参数‘name’,给view_func起个别名,实际上就是dispatch_request函数
    # 2.endpoint也可以不指定,则默认使用view_func的别名(name参数的值)
    app.add_url_rule('/list/', endpoint='list', view_func=ListView.as_view('list'))
    
    
    # url与视图映射
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run(port=5555)

    13-通过类的继承实现多个视图返回json数据

    from flask import Flask,url_for,views,jsonify
    
    app = Flask(__name__)
    app.config.update({
        'DEBUG':True,
        'TEMPLATES_AUTO_RELOAD':True
    })
    
    # 父类,把数据转换成json格式
    class JsonView(views.View):
        def get_data(self):
            raise NotImplementedError
    
        def dispatch_request(self):
            return jsonify(self.get_data())
    
    # 子类只需要写get_data方法
    class ListView(JsonView):
        def get_data(self):
            return {"usernmae":'derek','age':18}
    
    app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))
    
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    if __name__ == '__main__':
        app.run()

    14-基于调度方法的类视图

    class LoginView(views.MethodView):
        def __render(self,error=None):
            return render_template('login.html', error=error)
    
        def get(self,error=None):
            return self.__render()
    
        def post(self):
            username = request.form.get('username')
            password = request.form.get('password')
            if username == 'derek' and password == '123':
                return '登录成功'
            else:
                return self.__render(error='用户名或密码错误')
    
    app.add_url_rule('/login/',view_func=LoginView.as_view('login'))

     15-路由

    方式一:

      在Flask应用中定义路由的最简单方式,是使用应用实例提供的 app.route 装饰器。

    # url与视图映射
    @app.route('/')
    def hello_world():
        return 'Hello World!'

    方式二:

      使用 add_url_rule()方法。接收3个参数:URL,端点名和视图函数。

    16-Web开发服务器

    Flask应用自带Web服务器,通过 flask run 命令启动。这个命令在 FLASK_APP 环境变量指定的python脚本中寻找应用的实例。

    $ export FLASK_APP=hello.py
    
    $ flask run

    17-请求-响应循环

    17.1 应用和请求上下文

    为了避免大量可有可无的参数把视图函数弄得很乱,Flask使用 上下文 临时把一些变量变为全局可以访问。

    在Flask中有两种上下文:应用上下文和请求上下文。

    注意:获取应用上下文的方法是应用实例上调用 app.app_context()。

    17.2 请求分派

    17.3 请求对象

    Falsk通过上下文变量request对外开放请求对象,包含了客户端发送的HTTP请求的全部信息。

    Flask请求中最常用的属性和方法:

    17.4 请求钩子

  • 相关阅读:
    React: React的组件状态机制
    React: React的复合组件
    JavaScript:ES6的新特性
    React: 研究React的组件化
    React: 认识React
    CSS:CSS弹性盒子布局 Flexible Box
    iOS:应用程序扩展开发之Today扩展(Today Extesnsion)
    《逆向工程核心原理》
    《左手数据,右手图表》
    《设计模式之禅(第2版)》
  • 原文地址:https://www.cnblogs.com/pgxpython/p/10381905.html
Copyright © 2020-2023  润新知