如何从外部模块调用 web2py url?
How can I call a web2py url from an outside module?
我正在尝试从不同的模块获取由 web2py 生成的 html,以便我可以将其转换为 pdf 文件:
html = response.render('path/myview.html', context_dict)
我已将其包含在我的文件顶部:
sys.path.append('/home/www-data/web2py')
from gluon import *
但是,我仍然得到:
NameError: global name 'response' is not defined
也许有我没想到的更简单的方法?
您可以使用 gluon.template.render
函数执行 web2py 模板,但如果模板设计为在 web2py 应用程序中执行,它可能包含对某些 web2py 环境对象的引用(例如,HTML helper 对象、T
翻译对象、request
和 response
对象等),在 web2py HTTP 请求之外调用 render
函数时将不可用.
如果正确执行模板需要 web2py 环境,您可以使用 gluon.shell.env
函数构建一个:
import os
import gluon.shell
context_dict = {...} # The context to be passed to the template.
app = 'myapp'
app_path = os.path.join(os.path.dirname(os.path.abspath(gluon.shell.__file__)),
'..', '..', 'applications', app)
w2p_env = gluon.shell.env(app, dir=app_path, import_models=True)
context_dict.update(**w2p_env) # Update context with web2py environment objects.
response = w2p_env['response']
html = response.render(os.path.join(app_path, 'views', 'mycontroller', 'myview.html'),
context=context_dict)
gluon.shell.env
returns 包含所有 web2py 执行环境对象的字典。如果 import_models=True
,如上面的代码所示,它还会执行应用程序的模型(因此,模型中定义的任何对象也将包含在返回的字典中)。
通过使用完整的 web2py 执行环境更新 context_dict
,我们确保模板中引用的任何 web2py 对象(以及它扩展或包含的任何模板)都可用。
w2p_env
环境还包含一个response
对象,所以我们可以使用response.render
方法来渲染模板。或者,如上所述,我们可以使用 gluon.template.render
函数。
另一种方法是在您的 web2py 应用程序环境中简单地 运行 您的 Python 脚本:
python web2py.py -S myapp -M -R '/path/to/myscript.py'
通过这种方法,myscript.py 可以引用应用程序代码中可用的任何 web2py 环境对象(无需导入任何内容或显式构建 web2py 环境)。
此外,请注意,如果您不需要应用程序的模型是 运行,则可以排除 -M
。
我可以通过将我的 python 脚本添加到 web2py "modules" 文件夹中来让它工作。这样做之后,我不得不修改引用 "modules" 目录中其他文件的导入语句:
from applications.myapp.modules.mymodule import mystuff
from gluon import *
html = current.response.render('myview.html', context_dict)
然后从我使用的命令行 运行 它:
python /home/www-data/web2py/web2py.py -S myapp -R 'path/to/myscript.py'
正如安东尼所描述的那样
我计划在完成后从 cron 作业中调用此模块。我假设 web2py cron 将使用 web2py 环境,它不需要我用来测试的相同执行脚本。
我正在尝试从不同的模块获取由 web2py 生成的 html,以便我可以将其转换为 pdf 文件:
html = response.render('path/myview.html', context_dict)
我已将其包含在我的文件顶部:
sys.path.append('/home/www-data/web2py')
from gluon import *
但是,我仍然得到:
NameError: global name 'response' is not defined
也许有我没想到的更简单的方法?
您可以使用 gluon.template.render
函数执行 web2py 模板,但如果模板设计为在 web2py 应用程序中执行,它可能包含对某些 web2py 环境对象的引用(例如,HTML helper 对象、T
翻译对象、request
和 response
对象等),在 web2py HTTP 请求之外调用 render
函数时将不可用.
如果正确执行模板需要 web2py 环境,您可以使用 gluon.shell.env
函数构建一个:
import os
import gluon.shell
context_dict = {...} # The context to be passed to the template.
app = 'myapp'
app_path = os.path.join(os.path.dirname(os.path.abspath(gluon.shell.__file__)),
'..', '..', 'applications', app)
w2p_env = gluon.shell.env(app, dir=app_path, import_models=True)
context_dict.update(**w2p_env) # Update context with web2py environment objects.
response = w2p_env['response']
html = response.render(os.path.join(app_path, 'views', 'mycontroller', 'myview.html'),
context=context_dict)
gluon.shell.env
returns 包含所有 web2py 执行环境对象的字典。如果 import_models=True
,如上面的代码所示,它还会执行应用程序的模型(因此,模型中定义的任何对象也将包含在返回的字典中)。
通过使用完整的 web2py 执行环境更新 context_dict
,我们确保模板中引用的任何 web2py 对象(以及它扩展或包含的任何模板)都可用。
w2p_env
环境还包含一个response
对象,所以我们可以使用response.render
方法来渲染模板。或者,如上所述,我们可以使用 gluon.template.render
函数。
另一种方法是在您的 web2py 应用程序环境中简单地 运行 您的 Python 脚本:
python web2py.py -S myapp -M -R '/path/to/myscript.py'
通过这种方法,myscript.py 可以引用应用程序代码中可用的任何 web2py 环境对象(无需导入任何内容或显式构建 web2py 环境)。
此外,请注意,如果您不需要应用程序的模型是 运行,则可以排除 -M
。
我可以通过将我的 python 脚本添加到 web2py "modules" 文件夹中来让它工作。这样做之后,我不得不修改引用 "modules" 目录中其他文件的导入语句:
from applications.myapp.modules.mymodule import mystuff
from gluon import *
html = current.response.render('myview.html', context_dict)
然后从我使用的命令行 运行 它:
python /home/www-data/web2py/web2py.py -S myapp -R 'path/to/myscript.py'
正如安东尼所描述的那样
我计划在完成后从 cron 作业中调用此模块。我假设 web2py cron 将使用 web2py 环境,它不需要我用来测试的相同执行脚本。