Flask:如何在应用上下文之外使用 url_for()?



我正在编写一个脚本来收集那些没有收到电子邮件确认电子邮件的用户的电子邮件并将其重新发送给他们。 该脚本显然在烧瓶应用上下文之外工作。我想使用 url_for(( 但无法正确使用。

def resend(self, csv_path):
self.ctx.push()
with open(csv_path) as csv_file:
csv_reader = csv.reader(csv_file)
for row in csv_reader:
email = row[0]
url_token = AccountAdmin.generate_confirmation_token(email)
confirm_url = url_for('confirm_email', token=url_token, _external=True)
...
self.ctx.pop()

我要做的第一件事是在配置中设置SERVER_NAME。但是后来我收到此错误消息:

werkzeug.routing.BuildError: 无法为端点构建网址 带有值 ["令牌"的"confirm_email"。你的意思是"静态"吗?

这就是它的定义方式,但我认为它甚至找不到这个,因为它在作为脚本运行时没有注册:

app.add_url_rule('/v5/confirm_email/<token>', view_func=ConfirmEmailV5.as_view('confirm_email'))

有没有办法挽救url_for((还是我必须建立自己的网址? 谢谢

从应用程序上下文中获取 URL 要容易得多,也合适得多。

您可以导入应用程序并使用app_context手动推送上下文 https://flask.palletsprojects.com/en/2.0.x/appcontext/#manually-push-a-context

from flask import url_for
from whereyoudefineapp import application
application.config['SERVER_NAME'] = 'example.org'
with application.app_context():
url_for('yourblueprint.yourpage')

或者,您可以重新定义应用程序并注册所需的蓝图。

from flask import Flask, url_for
from whereyoudefineyourblueprint import myblueprint
application = Flask(__name__)
application.config['SERVER_NAME'] = 'example.org'
application.register_blueprint(myblueprint)
with application.app_context():
url_for('myblueprint.mypage')

我们也可以想象不同的方法来在没有应用程序的情况下做到这一点,但我看不到任何充分/适当的解决方案。

尽管如此,我仍然会建议这个肮脏的解决方案。

假设您有以下蓝图,其中包含routes.py中的以下路由。

from flask import Blueprint
frontend = Blueprint('frontend', __name__)
@frontend.route('/mypage')
def mypage():
return 'Hello'
@frontend.route('/some/other/page')
def someotherpage():
return 'Hi'
@frontend.route('/wow/<a>')
def wow(a):
return f'Hi {a}'

您可以使用库inspect获取源代码,然后对其进行解析以构建 URL。

import inspect
import re
BASE_URL = "https://example.org"
class FailToGetUrlException(Exception):
pass
def get_url(function, complete_url=True):
source = inspect.getsource(function)
lines = source.split("n")
for line in lines:
r = re.match(r'^@[a-zA-Z]+.route((["'])([^'"]+)1', line)
if r:
if complete_url:
return BASE_URL + r.group(2)
else:
return r.group(2)

raise FailToGetUrlException

from routes import *
print(get_url(mypage))
print(get_url(someotherpage))
print(get_url(wow).replace('<a>', '456'))

输出:

https://example.org/mypage
https://example.org/some/other/page
https://example.org/wow/456

相关内容

  • 没有找到相关文章

最新更新