1. 定义视图函数
视图函数是一个普通的Python函数,它接收请求并返回响应。视图函数通常与路由配合使用,通过装饰器将URL映射到视图函数。
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello, World!'
-
@app.route('/'):将根URL/映射到home视图函数 -
def home():视图函数,返回字符串作为响应
2. 接收请求数据
视图函数可以接收不同类型的请求数据,包括URL参数、表单数据、查询参数等。
获取URL参数(动态路由)
@app.route('/greet/<name>') def greet(name): return f'Hello, {name}!'
<name>是一个URL参数,Flask会自动将其传递给视图函数greet的同名参数。
获取表单数据(POST请求)
from flask import request @app.route('/submit', methods=['POST']) def submit(): username = request.form.get('username') return f'Form submitted by {username}!'
request.form.get('username'):获取POST请求中表单数据的username字段。
获取查询参数(GET请求)
@app.route('/search') def search(): query = request.args.get('query') return f'Search results for: {query}'
request.args.get('query'):获取GET请求URL中的查询参数query(如/search?query=flask)。
3. 返回响应
视图函数可以返回多种类型的响应,包括字符串、HTML模板、JSON数据或自定义响应对象。
返回字符串
@app.route('/message') def message(): return 'This is a simple message.'
返回HTML模板
from flask import render_template @app.route('/hello/<name>') def hello(name): return render_template('hello.html', name=name)
render_template('hello.html', name=name):渲染HTML模板hello.html,并将name变量传递给模板。
返回JSON数据
from flask import jsonify @app.route('/api/data') def api_data(): data = {'key': 'value', 'list': [1, 2, 3]} return jsonify(data)
jsonify(data):将Python字典转换为JSON响应,并自动设置Content-Type为application/json。
在Flask 2.2+中,直接返回字典或列表也会自动调用
jsonify(),因此可以简写为return data。
返回自定义响应对象
from flask import Response @app.route('/custom') def custom_response(): response = Response('Custom response with headers', status=200) response.headers['X-Custom-Header'] = 'Value' return response
Response():创建自定义响应对象,可以设置状态码和响应头。
4. 处理请求和响应
视图函数可以访问请求对象,并根据请求数据生成响应。
使用request对象
from flask import request @app.route('/info') def info(): user_agent = request.headers.get('User-Agent') method = request.method path = request.path return f'Method: {method}, Path: {path}, User-Agent: {user_agent}'
使用make_response创建响应
from flask import make_response @app.route('/header') def custom_header(): response = make_response('Response with custom header') response.headers['X-Custom-Header'] = 'Value' response.set_cookie('theme', 'dark') return response
make_response():创建响应对象并支持设置自定义头信息、Cookie等。
5. 处理错误
可以在视图函数中处理异常或错误,也可以通过Flask提供的错误处理机制来处理应用中的错误。
在视图函数中处理错误(try-except)
@app.route('/divide/<int:x>/<int:y>') def divide(x, y): try: result = x / y return f'Result: {result}' except ZeroDivisionError: return 'Error: Division by zero', 400
使用try-except语句处理除零错误,并返回自定义错误消息和状态码。
使用abort终止请求
from flask import abort @app.route('/post/<int:post_id>') def view_post(post_id): # 假设文章ID有效范围是1-100 if post_id < 1 or post_id > 100: abort(404, description='文章不存在') return f'<h1>文章 #{post_id}</h1>'
全局错误处理
@app.errorhandler(404) def not_found(error): return 'Page not found', 404 @app.errorhandler(500) def internal_error(error): return 'Internal server error', 500 @app.errorhandler(ZeroDivisionError) def handle_zero_division(error): return 'Cannot divide by zero', 400
@app.errorhandler():定义处理特定错误或异常的函数,可以捕获HTTP错误码或Python异常类。
6. 视图函数的装饰器(请求钩子)
除了@app.route,Flask还提供了多种装饰器,用于在请求处理的不同阶段执行自定义逻辑。
| 装饰器 | 触发时机 | 典型用途 |
|---|---|---|
@app.before_request |
每个请求处理之前 | 权限验证、数据库连接、请求日志 |
@app.before_first_request |
第一个请求处理之前(仅一次) | 初始化全局资源 |
@app.after_request |
每个请求处理之后,返回响应之前 | 添加响应头、压缩响应内容 |
@app.teardown_request |
请求结束后(无论是否有异常) | 释放资源、关闭数据库连接 |
示例:请求钩子使用
@app.before_request def before_request(): print('Before request') # 可以在这里做用户认证检查 # 如果未认证,可以返回响应提前终止请求 @app.after_request def after_request(response): print('After request') # 添加自定义响应头 response.headers['X-Request-Time'] = '123ms' return response @app.teardown_request def teardown_request(exception): print('Teardown request') # 清理资源,如关闭数据库连接 # 如果有异常,exception参数包含异常对象
多个钩子的执行顺序
请求到达 │ ▼ @app.before_request(按注册顺序执行) │ ▼ 路由匹配 → 视图函数执行 │ ▼ @app.after_request(按注册逆序执行) │ ▼ 响应返回客户端 │ ▼ @app.teardown_request(异常时也执行)
7. 视图函数返回的状态码
视图函数不仅可以返回内容,还可以指定HTTP状态码来表示请求的处理结果。
# 返回状态码200(成功) @app.route('/status') def status(): return 'Everything is OK', 200 # 返回状态码201(创建成功) @app.route('/create', methods=['POST']) def create(): return {'id': 1, 'message': 'Created'}, 201 # 返回状态码400(请求错误) @app.route('/validate') def validate(): return 'Invalid input', 400 # 返回状态码401(未认证) @app.route('/protected') def protected(): return 'Authentication required', 401 # 返回状态码403(无权限) @app.route('/admin') def admin(): return 'Access forbidden', 403 # 返回状态码404(未找到) @app.route('/old-page') def old_page(): return 'Page not found', 404 # 返回状态码500(服务器内部错误) @app.route('/error') def error(): return Response('Internal server error', status=500)
8. 视图函数返回值类型汇总
| 返回类型 | 示例 | Flask自动处理 |
|---|---|---|
str |
return "Hello" |
作为HTML响应体,200 OK |
dict |
return {"key": "value"} |
转为JSON响应,200 OK |
list |
return [1, 2, 3] |
转为JSON响应,200 OK |
tuple |
return "body", 404 |
自定义状态码 |
tuple |
return "body", {"X-Header": "v"} |
自定义响应头 |
Response |
return Response("body", status=200) |
完全控制的响应 |
render_template() |
return render_template("page.html") |
HTML模板渲染 |
jsonify() |
return jsonify(data) |
JSON响应 |
redirect() |
return redirect("/login") |
302重定向 |
abort() |
abort(404) |
错误响应 |
小结
本章详细讲解了Flask视图函数的完整知识体系。视图函数通过路由装饰器与URL绑定,通过request对象获取URL参数、表单数据、查询参数等请求信息;响应方面可以返回字符串、模板、JSON或自定义响应对象;错误处理可以通过try-except、abort()或@app.errorhandler()实现;请求钩子(@app.before_request、@app.after_request等)允许在请求处理的不同阶段执行统一逻辑;视图函数还可以通过元组或Response对象灵活指定状态码。这些知识构成了Flask应用业务逻辑编写的完整基础。