Bottle模板:如何导入Python包

3 投票
3 回答
1506 浏览
提问于 2025-04-17 19:08

我正在写一个简单的模板,想要比较一个日期。请问在模板里怎么导入Python的包?这样做可以吗?

这里有个例子,我想把一个表示日期的字符串和今天的日期进行比较:

%if datetime.strptime(report['date'], '%m/%d/%Y') < datetime.today():
    <span class="ui-icon ui-icon-circle-close"></span>
%elif report['result']:
    <span class="ui-icon ui-icon-circle-check"></span>
%elif not report['result']:
      <span class="ui-icon ui-icon-alert"></span>
%end

如果是在普通的Python程序中,我需要这样写:

from datetime import datetime

但是在模板里有办法做到这一点吗?

3 个回答

1

我刚刚试了一下:

%from mymodule import *

看起来是有效的,没时间再深入检查了。我觉得导入其实就是在调用一个Python的方法,所以应该是可以工作的。

2

是的,从模板内部导入模块可能的。比如,bottlepy本身就使用这种方式来生成错误页面:

ERROR_PAGE_TEMPLATE = """
%%try:
    %%from %s import DEBUG, HTTP_CODES, request, touni
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
        <head>
            <title>Error: {{e.status}}</title>
...
1

不,这样做是不可能的。模板不应该包含复杂的逻辑,它们主要是用来展示内容的。你应该在视图中准备好所有的数据,然后把处理好的数据传递给模板。

所以在你的情况下,应该把逻辑放到视图中,结果可能会像这样:

from datetime import datetime
if datetime.strptime(report['date'], '%m/%d/%Y') > datetime.today():
    report["status"] = "due"
else:
    if report["result"]:
        report["status"] = "pending_check"
    else:
        report["status"] = "missing_result"

然后在模板中检查这个标志,像这样:

%if report["status"] == "due":
    <span class="ui-icon ui-icon-circle-close"></span>
%elif report["status"] == "pending_check":
    <span class="ui-icon ui-icon-circle-check"></span>
%elif report["status"] == "missing_result":
      <span class="ui-icon ui-icon-alert"></span>
%end

我故意没有使用 closecheckalert 作为 report["status"] 的值,因为最佳做法是将数据和展示分开,因此在视图中不要直接给 HTML 类名,而是像我在附带的代码片段中那样在模板中处理数据。

这样,如果你决定更改图标,只需要在模板中进行修改,这比在视图中做展示上的更改要好(比如说,不用重启你的网络服务器就能看到效果)。

更新(2016年4月):显然,自从我回答这个问题以来,现在在 Bottle 模板中导入模块是可能的,但这仍然不是个好主意 :)

撰写回答