我的问题的起源是一个表单的验证器函数,它被定义为:
def AirlineICAORequired():
"""
Validates whether string is a valid ICAO code
"""
message = '''Must be an airline ICAO code. Please refer to: <a id="err-icao" href="{{ url_for('api.airlines') }}" class="link-danger">List of Airlines</a> for a list of airlines with ICAO codes listed.'''
def _airlineicao(form, field):
airline = get_airline(field.data)
if not airline:
raise ValidationError(message)
return _airlineicao
请注意,我正在呈现一个html a标记,我试图将“API.airlines”路线的URL呈现到该标记。我有以下问题要考虑:
1.我不能从from flask import current_app
或从app.py定义为app
的实际应用示例中使用app_context,原因如下:
a)with current_app.app_context():...
仍然会引发RuntimeError,表明我正在应用程序上下文之外工作
B)如果我试图在函数所在的文件(forms.py)中导入from app import app
,那么我将遇到一个循环导入错误,因为其他文件,如routes.py(它有一个Blueprint,并在app.py中导入)从这个文件导入。
在html文件中,我将错误消息加载为:
{% for error in initializer_form.initializer.errors %}
<li class="list-group-item list-group-item-danger">
{{ error|safe }}
</li>
{% endfor %}
不幸的是,这会导致以下html行:
<li class="list-group-item list-group-item-danger">
Must be an airline ICAO code. Please refer to: <a id="err-icao" href="{{ url_for('api.airlines') }}" class="link-danger">List of Airlines</a> for a list of airlines with ICAO codes listed.
</li>
对于上下文,initializer_form
是设置同一验证器进行验证的形式。
这里还有一张图片,它在网站中的样子,如果点击“航空公司列表”,则会重定向到底部的URL:
其他有用信息:
项目文件结构及相关文件显示:
routelookup/
├─ Config/
├─ data/
├─ static/
├─ templates/
├─ api.py
├─ app.py
├─ form.py
├─ routes.py
导入(所有文件的导入都在文件的顶部):
- app.py:*
# imports
from flask import Flask
from routes import routes
from api import api
from routeparser import reset_contents, fr_api_logout
from Config import config
import atexit
- form.py:*
# imports
from flask_wtf import FlaskForm
from routeparser import get_airline
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired, Email, Length, ValidationError
- routes.py:*
# Imports
from flask import Blueprint, render_template, redirect, url_for
from pathlib import Path
from forms import AirlineInitForm
我想要的
如果我想得到正确的网址到href,而不是如上所示通过图像和第二html代码块,我怎么能考虑到我的问题,如果我想做的事情,通过使用url_for
或类似的东西,而不是硬编码它?
编辑1
日期:10/2/23
我创建了一个名为form_validators的新文件,它的部分内容如下所示:
# imports
from flask import url_for
from app import app
from routeparser import get_airline
from wtforms.validators import ValidationError
# Relavant validator to the issue
def AirlineICAORequired():
"""
Validates whether string is a valid ICAO code
"""
with app.app_context():
message = f'''Must be an airline ICAO code. Please refer to: <a id="err-icao" href="{url_for('api.airlines') }" class="link-danger">List of Airlines</a> for a list of airlines with ICAO codes listed.'''
def _airlineicao(form, field):
airline = get_airline(field.data)
if not airline:
raise ValidationError(message)
return _airlineicao
所有的验证器都被移动到这个文件与相关的进口。
仅导入添加到forms.py
:
from form_validators import AtLength, AirlineICAORequired
1条答案
按热度按时间zengzsys1#
所以我解决了我的问题。我要感谢@PGHE尽可能多地帮助我,这激励我更深入地研究我自己的问题。我做了以下修改,其中一些可以在“编辑1”中看到的问题。为了总结这一点,我创建了一个新文件,名为:“forms_validators.py”在这里我将添加所有自定义验证器并将它们分别导入到“forms.py“。至于我需要“修复”的验证器,我做了以下更改,如下面的代码块所示:
这一点很重要,我们将在后面的回答中看到。这只是增加了对添加消息的支持,以便在验证器使表单数据无效时替换显示的默认消息。
根据
form.py
,我删除了导入:AirlineICAORequired
来自form_validators.py
,在表单中,我添加了一个方法,在输入字段添加到设置了验证器的表单中之后添加验证器:至于路由页面,我确定我将能够使用
url_for
,而没有任何应用程序上下文等问题。由此可见:在检查表单有效性(
if form.validate_on_submit()
)之前,我添加了验证器(AirlineICAORequired
),我需要通过后面提到的方法添加到表单类中,使用url_for
来获取我想要的航空公司API路线的URL,将其添加到f字符串中,如果验证失败,则会发送错误消息。