flask学习记录05-flask中的请求钩子

本文详细介绍了Flask框架中的请求钩子功能,包括before_first_request、before_request、after_request和teardown_request四个装饰器的用途及使用方法,并通过实例展示了如何利用这些钩子进行请求的预处理和后处理。

图片

这节是flask-视图函数及路由模块的最后一个章节,下一节将开始记录flask-模块相关的知识。

请求钩子的作用

请求钩子是通过装饰器的形式实现的,其目的就是避免写重复的代码.

在客户端和服务器交互的过程中,做些准备工作和扫尾工作.

flask中有哪些装饰器

  • before_first_request

  • before_request

  • after_request

  • teardown_request

请求钩子该如何使用

before_first_request
  • 处理第一个请求前执行

  • 只执行一次

  • 不能拦截第一次请求的执行

写一个实例,来看下before_first_request,该怎么用

图片

可以看到before_first_request只执行一次,且在第一个请求前进行执行,我们分析下它在浏览器中的执行过程

图片

before_request
  • 在每次请求前都执行

  • 对应的函数如果返回一个响应,视图函数不被调用

写一个实例来看下before_request怎么用

图片

可以看到它每次都会执行,如果返回响应,函数就不被调用了

图片

基于这个特性,我们是不是可以在对应的函数中,在请求开始之前,做一些处理。

比如典型的需求,对一些非法的请求进行拦截.我们可以在before_request请求钩子对应的函数中,写个if语句判断ip是否在黑名单里,如果在直接返回提示信息

after_request
  • 必须接收一个response对象

  • 必须返回一个response对象

  • 对应的函数中可以对response对象进行处理

写一个实例来看下after_request怎么用,发现页面报错了

图片

看样子是缺少一个参数,我们查询源码看下

图片

原来忘记接收和返回response返回对象了,我们加入看下,是不是可以了

图片

teardown_request
  • 每次请求执行之后

  • 必须接收一个error对象

  • 如果请求异常,对应的函数可捕获具体异常

写一个实例来看下teardown_request怎么用,发现页面又报错了

图片

看样子,还是缺少一个参数,我们继续看下源码要求的参数

图片

原来必须接收一个error对象,我们添加参数,发现已经成功了

图片

请求钩子在项目中有很大的用处,这里只是一些简单的入门操作,后续在项目中可以具体应用

<think> 我们正在讨论Flask-WTF表单库,用户希望了解如何自定义表单提交逻辑并处理服务器返回值。 根据引用[4],我们看到一个示例视图函数`new_note`,它处理一个表单的提交。这里使用了`form.validate_on_submit()`来检查表单是否通过验证(即是否是POST请求并且验证成功)。如果验证成功,则获取表单数据,创建笔记对象,保存到数据库,然后重定向到首页。 用户的问题主要集中在两点: 1. 如何自定义修改提交逻辑? 2. 如何接收服务器的返回值并处理? 在Flask-WTF中,表单的提交逻辑通常是在视图函数中控制的。我们可以通过覆盖表单的`validate_on_submit`方法后的处理流程来自定义逻辑。 关于接收服务器返回值并处理:在Flask中,服务器处理后的返回值通常是通过重定向、渲染模板或直接返回响应(如JSON)来传递的。客户端(浏览器)接收这个响应并进行处理(如显示消息、跳转页面等)。如果使用AJAX,则可以在客户端使用JavaScript处理服务器返回的JSON数据。 下面我将详细说明: 一、自定义提交逻辑: 通常,一个表单视图的基本结构如下(如引用[4]所示): ```python @app.route('/new', methods=['GET','POST']) def new_note(): form = NewNoteForm() if form.validate_on_submit(): # 在这里编写表单验证通过后的逻辑 # 例如:获取数据、保存到数据库 flash('操作成功!') # 使用flash发送反馈消息 return redirect(url_for('index')) # 重定向 # 如果是GET请求或验证未通过,则渲染表单 return render_template('new_note.html', form=form) ``` 自定义提交逻辑可以在`if form.validate_on_submit():`下面的代码块中实现。例如,你可能需要: - 对表单数据进行额外的处理(如加密、计算等) - 根据条件判断是否真的提交(比如检查数据库中的重复项) - 发送邮件、调用外部API等操作 二、接收服务器返回值并处理: 在传统的表单提交中,服务器返回一个重定向或一个HTML页面。客户端浏览器会加载新的页面。我们可以使用`flash`消息来传递一次性消息,然后在模板中显示这些消息。 然而,如果希望在不刷新页面的情况下提交表单并处理返回的数据(例如,返回一段JSON数据),那么就需要使用AJAX。 下面是一个使用jQuery和Flask处理AJAX表单提交的示例: 1. 在表单中,阻止默认的提交行为,使用AJAX提交数据。 2. 在服务器端,根据请求是否是AJAX(通过`request.is_xhr`判断,或者使用`request.json`或`request.get_json()`)来返回JSON响应。 客户端代码(JavaScript)示例: ```javascript $(document).ready(function() { $('form').submit(function(event) { event.preventDefault(); // 阻止表单默认提交 var form = $(this); $.ajax({ type: form.attr('method'), url: form.attr('action'), data: form.serialize(), success: function(response) { // 处理服务器返回的响应 if (response.success) { // 显示成功消息 alert(response.message); // 或者重定向 window.location.href = response.redirect_url; } else { // 显示错误信息 alert(response.message); } }, error: function() { alert('请求失败'); } }); }); }); ``` 服务器端视图函数示例(返回JSON): ```python from flask import jsonify @app.route('/new', methods=['GET','POST']) def new_note(): form = NewNoteForm() if form.validate_on_submit(): # 处理表单数据... # 如果请求是AJAX请求,返回JSON if request.is_xhr: # 或者使用 request.headers.get('X-Requested-With') == 'XMLHttpRequest' response = { 'success': True, 'message': '操作成功!', 'redirect_url': url_for('index') } return jsonify(response) else: flash('操作成功!') return redirect(url_for('index')) else: # 验证失败的处理 if request.is_xhr: response = { 'success': False, 'message': '表单验证失败', 'errors': form.errors # 将表单的错误信息返回 } return jsonify(response), 400 else: # 非AJAX请求,则返回表单页面(并显示错误信息) return render_template('new_note.html', form=form) ``` 注意:在Flask中,`request.is_xhr`属性在较新的版本中已被弃用,建议使用`request.headers.get('X-Requested-With') == 'XMLHttpRequest'`来判断是否为AJAX请求。 另外,如果使用Flask-WTF的表单,在AJAX提交时,不要忘记在表单中包含CSRF令牌。可以在表单中添加一个隐藏字段: ```html <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> ``` 然后在AJAX请求中正常提交即可。 总结: - 自定义提交逻辑:在`form.validate_on_submit()`之后的代码块中编写自己的逻辑。 - 接收处理服务器返回值:对于传统表单,使用重定向和flash消息;对于AJAX表单,返回JSON响应,并在客户端用JavaScript处理。 希望这能帮助用户解决问题。 根据要求,生成相关问题: §§相关问题§§ 1. 如何在Flask-WTF表单中添加CSRF保护? 2. 如何使用Flask的flash消息并在模板中显示? 3. 在Flask中如何处理表单验证错误并返回给AJAX请求? 4. 除了jQuery,还有哪些方法可以在前端实现AJAX表单提交? 5. 如何对Flask-WTF表单进行自定义验证(比如添加一个自定义的验证器)? </think> 在 Flask-WTF 中自定义表单提交逻辑并处理服务器返回值,主要通过覆盖表单验证方法、自定义视图函数逻辑和使用 AJAX 技术实现。以下是具体方法: ### 1. **基础表单提交处理** 参考引用[4],使用 `validate_on_submit()` 结合自定义逻辑: ```python from flask import request, jsonify @app.route('/submit', methods=['POST']) def submit_form(): form = CustomForm() # 自定义提交逻辑 if form.validate_on_submit(): # 自定义处理逻辑(如数据库操作) result = process_data(form.data) # 处理服务器返回值 if result['success']: return jsonify({"status": "success", "message": "操作成功"}) else: return jsonify({"status": "error", "message": result['error']}), 400 return jsonify({"status": "error", "errors": form.errors}), 400 ``` ### 2. **自定义验证逻辑** 在表单类中覆盖 `validate()` 方法: ```python from wtforms import Form, StringField, validators class CustomForm(Form): name = StringField('姓名', [validators.InputRequired()]) def validate(self): # 先执行默认验证 if not super().validate(): return False # 自定义验证规则 if "admin" in self.name.data: self.name.errors.append("不能包含敏感词") return False return True ``` ### 3. **AJAX 异步处理(前端交互)** 参考引用[2][4],结合前端处理返回值: ```python # 后端视图(返回JSON) @app.route('/ajax-submit', methods=['POST']) def ajax_submit(): form = CustomForm(request.form) if form.validate(): # 处理业务逻辑... return jsonify({"code": 200, "message": "操作成功"}) return jsonify({"code": 400, "errors": form.errors}), 400 ``` ```javascript // 前端JavaScript(使用jQuery示例) $("#myForm").submit(function(e){ e.preventDefault(); $.ajax({ url: '/ajax-submit', type: 'POST', data: $(this).serialize(), success: function(response){ if(response.code === 200) { alert("成功: " + response.message); } else { // 显示错误信息 $.each(response.errors, function(key, value){ $("#"+key+"-error").text(value[0]); }); } } }); }); ``` ### 4. **高级回调处理** 使用 `after_validation` 钩子扩展逻辑: ```python from flask_wtf import FlaskForm class CallbackForm(FlaskForm): def after_validation(self): # 在所有验证完成后执行 if self.name.data == "test": self.custom_flag = "特殊用户处理" ``` ### 关键点说明: 1. **返回值处理**: - 传统表单:通过 `redirect()`/`flash()` 返回结果(引用[4]) - AJAX 表单:返回结构化 JSON(`jsonify()`) 2. **错误控制**: - 使用 `abort(400)` 中断流程(引用[2]) - 自定义错误处理器 `@app.errorhandler(400)`(引用[2]) 3. **数据流扩展**: - 在验证通过后添加业务逻辑(如数据库操作,引用[4][5]) - 预处理/后处理钩子扩展验证流程 > 示例参考:自定义表单提交后调用外部 API 并处理响应值: > ```python > if form.validate_on_submit(): > api_response = requests.post('https://api.service.com', json=form.data) > if api_response.status_code == 200: > return jsonify(api_response.json()) > form.errors['api'] = ['第三方服务错误'] # 添加自定义错误 > ``` [^1] [^2] [^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐风的测开笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值