Flask 快速入门

一、Flask 简介

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。

Flask也被称为 “microframework” ,因为它使用简单的核心,并且被设计为可扩展形式。故而没有提供一些重要的功能,例如数据库和用户认证,所以开发者可以自由选择最适合程序的包,或者按照需求自行开发。

社区成员开发了大量的不同用途的扩展,如果这还不能满足需求,你还可以使用所有Python标准包或代码库。

Flask 快速入门_第1张图片
image.png

二、Flask 安装

一般安装python后会自带pip工具,方便下载安装python各类库,如果没有自行百度。

pip install flask

三、最简单Flask应用

# app.py
from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
    return "Hello World!"

if __name__ == '__main__':
    app.run() # 启动服务器

写完后直接用python运行,默认监听本地5000端口,访问http://127.0.0.1:5000/就能看到Hello World!

四、初始化应用

所有Flask程序都必须创建一个程序实例,所有功能都是围绕这个实例进行的,接收自客户端的所有请求都将转交到这个对象处理。程序实例是Flask类的对象,经常使用下述代码创建一个实例:

from flask import Flask
app = Flask(__name__)

五、路由和视图函数

  • 路由

客户端(如Web浏览器)把请求发送给Web服务器,Web服务器再把请求发送给Flask程序实例,程序实例需要知道对每个URL请求运行哪些代码,所以保存了一个URL到Python函数的映射关系。处理URL和函数之间关系的程序称为路由

  • 视图函数

前面最简单的Flask应用中定义了一个函数hello_world(),该函数被注册为程序根地址(/)的处理程序,也就是访问http://127.0.0.1:5000/时,会触发服务器执行hello_world()函数,函数的返回值成为响应,是客户端接收到的内容,如果客户端是Web浏览器,响应就是返回给用户的HTML文档。
hello_world()这样的用于处理请求的函数称为视图函数。视图函数可以返回简单的HTML字符串,也可以返回一个完整的HTML文档(这里就要用到Jinja2模板引擎啦)。

  • 注册一个视图函数最常用的方法就是用app.route():
@app.route("/")
def hello_world():
    pass
  • 限制路由的请求方法
@app.route("/", methods=["GET"])
def hello_world():
    pass

这样,要是客户端以POST的方式请求该路由,就会返回“405 Method Not Allowed”

  • 向路由函数传参
    有的时候我们需要通过url获取有用的信息,比如说知道来访者的姓名,以便在返回的欢迎语中加入他的名字。
@app.route("/hello/")
def hello(name):
   return "hello, " + name

上例中,在定义该路由的访问路径里加了一个,并增加了一个同名函数参数。
更一般的情况是,其中type是类型,常用的有string、int,param就是参数名,它会传递到路由函数的同名参数里。

六、启动服务器

当Flask应用被初始化且视图函数定义好之后,就可以启动Flask应用啦。

if __name__ == "__main__":
    app.run() # 默认监听本地5000端口
    # app.run(port=8080) 监听8080端口

七、请求 - 响应循环

说到请求,必须要先介绍一下上下文

  • 上下文(Context)

上下文,在阅读文章时经常提到,意思是语境、语意。在程序设计中,上下文的概念也是类似的,你可以这么理解:
通俗地讲,每一段代码都有许多外部变量,比如一个函数需要传入若干个必填的参数才能够运行,那些参数就是上下文的一部分,意味着该函数无法独立运行,需要上下文的支持。而许多函数都是需要各种参数才能运行的,这些参数组成的集合就称为上下文。

  • Flask中的上下文

变量名 上下文 说明
current_app 程序上下文 当前激活程序的程序实例
g 程序上下文 上下文全局变量
request 请求上下文 请求对象,封装了客户端发出的HTTP请求中的内容
session 请求上下文 用户会话,用户储存同一个客户端在多个请求间需要“记住”的信息
  • 请求上下文

请求上下文变量是在视图函数被触发时传入的一个HTTP请求对象,储存了所有客户端发送过来的数据,因此该变量只有在视图函数中才能访问。如果难以理解,你只需要记住request变量只有在视图函数中才能访问
我们可以通过以下方式引入请求上下文变量:

from flask import request
  • 请求上下文变量常用的访问操作有:

    request.args 获取所有GET请求参数
    request.form 获取所有form-data、x-www-form-urlencoded类型的请求参数
    request.json 获取所有json类型的请求参数
    request.method 获取请求方法
    request.headers 获取请求头

  • 请求钩子

    • 什么是钩子(Hook)?
      打个比方,鱼钩是用来钓鱼的,一旦鱼咬了钩,钩子就一直钩住鱼了,任凭鱼在水里怎么游,也逃不出鱼钩的控制。在程序设计里,钩子就是一个事件,钩住了某段代码,任凭这段代码这么运行,都逃不过我的钩子事件。

    • Flask里的请求钩子

      钩子 说明
      before_first_request 注册一个函数,在处理第一个请求之前运行
      before_request 注册一个函数,在每次请求之前运行
      after_request 注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行
      teardown_request 注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行
    • 用法

    from flask import request
    
    @app.before_request
    def app_before_request():
        print("HTTP {}  {}".format(request.method, request.url))
    

    这样在每次请求时都会输出请求方式和请求url,但其实钩子函数的作用远不止这些。

  • 响应

    通常,每个视图函数都有返回值,而最简单的就是一串字符串了,Flask默认返回的类型是text/html,状态码为200。状态码很重要,如果需要修改,我们可以这样做:

    @app.route("/")
    def hello_word():
        return "Not Found", 404
    

    当然,如果要自定义响应,最好还是引入make_response函数,该函数接受一个bytes对象(二进制数据)或者字符串作为响应主体,并返回一个响应对象response,通过这个对象我们可以自定义该响应的头部,比如修改响应头部的Content-Type和Content-Disposition来告诉客户端这个文件是需要被下载的,并且将From设置为Ncuhome来告诉客户端该文件来自家园工作室。

    @app.route("/download")
    def download():
      response = make_response(open("lesson.md", "rb").read())
      response.headers["From"] = "Ncuhome"
      response.headers["Content-Type"] = "application/octet-stream; charset=utf-8;"
      response.headers["Content-Disposition"] = "attachment;filename=lesson.md"
      return response
    
  • 快速构建一个json格式的响应

    前后端交互时,一般都是使用JSON格式数据进行交互

    from flask import jsonify
    @app.route('/hello', methods=['GET'])
    def user(user_id):
        if not user_id == 1:
            abort(404)
    
        return jsonify({
            "status": 1,
            "data": {
                "username": "ncuhome",
                "desc": "Hello, Ncuhomer!",
            },
            "message": "获取成功"
        })
    
  • 其他一些响应

    • 重定向
    from flask import redirect
    @app.route("/ncuos")
    def ncuos():
        return redirect("https://www.ncuos.com/")
    
    • 重定向到某个路由
    from flask import url_for
    @app.route("/redirect_to_hello")
    def redirect():
        return redirect(url_for("hello"))
    
    @app.route("/hello")
    def hello():
        return "Hello, Ncuhomer!"
    
    • 返回HTTP状态码
    from flask import abort
    @app.route("/user/")
    def get_user(user_id):
        abort(404)
    

Jinja2 模板引擎

前面提到了Jinja2,它的作用其实是为了方便构造HTML文档、以及其他的一些文档内容(邮件等)。

  • 响应返回完整HTML
    简单举个栗子吧
    模板文件 ./template/index.html
    
    
    
        
        Ncuhome Demo
    
    
        Hello, {{ name }}
    
    
    
    其中name就是我们需要填补的,它用花括号{{ }}括起来了。
    填补name并返回完整HTML:
     from flask import render_template
     @app.route("/hello/")
     def hello(name):
         return render_template("index.html", name=name)
    
  • 模板中的for循环
    
    
    
        
        Ncuhome Demo
    
    
      {% for user in users %}
      {{ loop.index }}: {{ user }} 
    {% endfor %}
     from flask import render_template
     @app.route("/users")
     def hello(name):
         users = ["Amy", "David", "Sam"]
         return render_template("index.html", users=users)
    
  • 模板中的if
    if和for类似,都拥有一个作用域,用法也一样。
    {% if name %}
       {{ name }}
    {% endif %}
    

你可能感兴趣的:(Flask 快速入门)