人生苦短,我用Flask

Flask是一个轻量级的Python Web开发框架,以其扩展性和简洁性著称。本文详细介绍了Flask的基本使用,包括环境搭建、路由定义、HTTP方法支持、动态URL映射、请求对象、响应处理、会话管理、错误处理、蓝图以及装饰器等核心概念。通过实例展示了如何创建一个简单的Flask应用,并探讨了其在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是 Flask

Flask 怎么用

搭建环境

最基本的应用

from Flask import flask

app = Flask(__name__)


@app.route('/')
def index():
	return '<h1> hello world! </h1>'
	

if __name__ == '__main__':
	app.run()

路由

Flask 中,路由是指 用户请求的 URL 与视图函数之间的映射,且 URL 后的 / 默认严格要求,即 /a 和 /a/ 代表两个路由,但是 Flask 访问 /a 时会做一次重定向访问到 /a/ 可在路由装饰器中设置 strict_slashes=False 忽略该条件

注册路由
  • 路由装饰器:将一个 URL 规则绑定到一个视图函数上
# 通常使用
@app.route('/hello')
def hello():
	return '<h1> hello world! </h1>'

# 或这一种,但比较麻烦,而且不够优雅,不推荐使用
app.add_url_rule('/test', view_func=test)
为路由指定 HTTP 方法
  • Flask 路由默认只支持 GET 请求,但可通过关键字 methods 指定其他一种或多种 HTTP 方法

    @app.route('/login', methods=['GET', 'POST'])
    def hello():
    	return '<h1> hello world! </h1>'
    
匹配动态URL

同一类 URL 映射到同一个视图函数处理,比如根据不同 username 查询不同用户信息

@app.route('/user/<uname>')
def query_user(uname):
  return f'hello {uname}'
URL 变量类型过滤
  • 在Flask中,转换器/converter用来对从 URL 中提取的变量进行预处理,这个过程 发生在调用视图函数之前。Flask 预置了四种转换器:

    • string:匹配不包含 / 的字符串,默认转换器
    • path:匹配包含 / 的字符串
    • int:只有当前 url 中的变量是整形值时才匹配,并将变量转换成整型
    • float:只有当前 URL 变量中是浮点型时才匹配,并将变量转换成浮点型
    from flask import request, Blueprint
    
    # 蓝图生成
    ak = Blueprint('ak', __name__, url_prefix='/api/ak')
    
    # 蓝图注册
    app.register_blueprint(ak)
    
    @ak.route('/<int:name_or_id>', methods=['DELETE'])
    @has_perm('ak_delete')
    def delete_ak(name_or_id):
        if name_or_id.isdigit():
            id_ = int(name_or_id)
            akm_client.delete_ak(None, id_, zone=zone)
        else:
            akm_client.delete_ak(name_or_id, None, zone=zone)
        return json_ok()
      
    # /api/ak/123           OK 
    # /api/ak/hello/123   不 OK
    # /api/ak/12.2				不 OK
    

请求 request 对象

  • 封装了客户端的请求参数

    from Flask import request
    
    # 获取从客户端 URL 中传输过来的查询字符串
    request.args
    # 获取从客户端表单中提交的信息
    request.form
    # 获取从客户端请求body中的 json 字符串
    request.json
    # 获取客户端使用的方法
    request.method
    # 获取从客户端请求过来的文件
    request.files
    # 访问cookie
    reques.cookies
    
  • 是一个全局对象

  • 线程隔离,必须运行在当前请求中的上下文,否则报错

重定向和错误

from Flask import redirect

@app.route('/')
def index():
	return '<h1> hello world! </h1>'


@app.route('/login/', methods=['POST'])
def login():
  # url 跳转
  return redirect('/hello/index/')
  # url_for 根据别名反向解析路由
  return redirect(url_for('index'))
	# 使用 abort() 直接退出请求
  abort(404)
  print('here is never executed')

响应 make_response

视图函数的返回值会自动转换为一个响应对象。

如果返回值是一个字符串,那么会被 转换为一个包含作为响应体的字符串、一个 200 OK 代码 和一个 text/html 类型的响应对象。

如果返回值是一个字典,那么会调用 jsonify() 来产生一个响应。以下是转换的规则:

  1. 如果视图返回的是一个响应对象,那么就直接返回它。
  2. 如果返回的是一个字符串,那么根据这个字符串和缺省参数生成一个用于返回的 响应对象。
  3. 如果返回的是一个字典,那么调用 jsonify 创建一个响应对象。
  4. 如果返回的是一个元组,那么元组中的项目可以提供额外的信息。元组中必须至少 包含一个项目,且项目应当由 (response, status)(response, headers) 或者 (response, status, headers) 组成。 status 的值会重载状态代码, headers 是一个由额外头部值组成的列表 或字典。
  5. 如果以上都不是,那么 Flask 会假定返回值是一个有效的 WSGI 应用并把它转换为 一个响应对象。

如果想要在视图内部掌控响应对象的结果,那么可以使用 make_response() 函数。

from Flask import make_response


@app.route('/')
def index():
  # 返回内容
  resp = make_response('<h1> hello world </h1>')
  # 返回页面
  resp = make_response(render_template('xx.html'))
  # 返回状态码
  resp = make_response(render_template('xx.html'), 200)
  # 设置 cookie 
  resp.set_cookie('xx', 'xx')
  # 设置 header
  resp.headers['X-Something'] = 'A value'
	return resp
session
  • 使用 session 前必须设置一个密钥,这个密钥相当于 MD5 加密的盐

    from flask import Flask, session, redirect, url_for, escape, request
    
    app = Flask(__name__)
    
    app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
    
    @app.route('/')
    def index():
        print(session['xxx'])
        return 'xxx'
    

hooks

将被装饰的函数注册到 app 中,在不同的阶段执行

  • before_first_request:在处理第一次请求前执行

  • before_request:在每次请求前执行(先于视图函数)

  • after_request:无未处理的异常抛出每次请求后执行(后于视图函数)

  • teardown_request:每次请求后执行

  • errorhandler:根据不同的错误状态码或异常

    @app.errorhandler(LoginRequired)
    def login_redirect(e):
    login_url = current_app.sso_config.login_url
    return json_error(e, BaseErrorCode.LOGIN_REQUIRED)
    
    @app.errorhandler(500)
    def internal_server_error(e):
    return json_error(e, 'ooooops, server crashed!')
    

蓝图

蓝图将应用进行模块化,能够很方便的将不同的功能和路由区分开,并且易于维护,蓝图基于相同的url前缀来作区分。

from flask import request, Blueprint

# 蓝图生成
ak = Blueprint('ak', __name__, url_prefix='/api/ak')

# 蓝图注册
app.register_blueprint(ak)


@ak.route('/<name_or_id>', methods=['DELETE'])
@has_perm('ak_delete')
def delete_ak(name_or_id):
    if name_or_id.isdigit():
        id_ = int(name_or_id)
        akm_client.delete_ak(None, id_, zone=zone)
    else:
        akm_client.delete_ak(name_or_id, None, zone='default')
    return json_ok()

扩展

python 装饰器 与 java 注解
python 装饰器
  • 和名字一样,思想是一种装饰器模式思想

  • 本质是一个 Python 函数或者类,可以让使用装饰器的类或函数在不需要任何代码修改的前提下增加额外功能,返回值是一个函数或类

  • 只能用于类或函数

  • 与 Java 一样可实现面向切面编程,python的一种语法糖

一个简单的装饰器

def log(func):                                      #@1
    def func_dec(*args, **kwargs):                  #@2
        r = func(*args, **kwargs)                   #@3
        print("execute done:%s" % func.__name__)
        return r
 
    return func_dec
 
@log                                                #@4
def test_dec(size, length, ky=None):
    print "execute test_dec param:%s, %s, %s" % (size, length, ky)
 
 
def test():
    test_dec(ky="xxx", length=3, size=1)

    
输出:
  execute test_dec param:1, 3, xxx
  execute done:test_dec
java 注解
  • Java注解本质是 k-v 对,会在编译期给类增加元信息,配合反射可以实现面向切换编程
  • 总的来说要比python的装饰器功能强大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值