我认为模板相当于方法。
确实如此 IPO (输入-处理-输出):
- 它需要一些输入。
- 它做一些处理
- 它输出一些东西。很可能是 HTML。
在 Python 中,方法具有必需参数和可选参数(具有默认值)。
有没有办法为 Django 模板定义(我称之为)API?
- 我需要一些参数。
- 我希望一些参数具有默认值。
用例:客户可以通过网络界面编辑模板。我想告诉客户对模板的更改是否有效。
我可以渲染模板以查看是否发生错误,但这不包括这种情况:
模板应呈现值“foo_needs_to_get_rendered”。
在这种情况下,通过渲染(并丢弃结果)验证模板不会显示错误。
相关:我想向编辑模板的客户显示一条帮助消息。我想列出上下文的所有可用变量。示例:“您可以使用这些变量:{{foo}}、{{bar}}、{{blue}} ...”
最佳答案
Django 模板首先在 Context
对象(一种字典)中查找键。如果 key 不存在,则会引发 KeyError
,这会被模板引擎捕获。通常情况下, key 会呈现为空白。
所以在我看来,如果你想绕过这种行为,你需要让一个丢失的键引发 KeyError 以外的东西。或者,您可以在模板引擎捕获之前捕获 KeyError
,并在重新引发之前保存该信息。
您可以通过子类化 Context
来做到这一点,这需要对模板引擎代码进行一些研究……但这可能是一个非常好的方法。但是您也可以将您的 API 包装在一个执行此操作的特殊类中……并将其放在上下文中。以下代码尚未经过测试。将其视为伪代码,您可以将其用作起点...
# our own KeyError class that won't be caught by django
class APIKeyError(Exception):
pass
class API(object):
def __init__(self, context, exc_class=APIKeyError):
self.context = context
self.exc_class = exc_class
self.invalid_keys = set()
self.used_keys = set()
@property
def unused_keys(self):
return set(self.context.keys()) - self.used_keys
def __getattr__(self, name):
try:
value = self.context.get(name)
self.used_keys.add(name)
return value
except KeyError:
self.invalid_keys.add(name)
if self.exc_class is None:
raise
raise self.exc_class(
'API key "%s" is not valid. Available keys are %s.' %
(name, self.context.keys()))
然后你会像这样检查你的模板:
from django.template.loader import render_to_string
api = API({
'foo': 'foovalue',
'bar': 'barvalue',
'baz': 'bazvalue',
}, None)
render_to_string('template.html', {'api': api }, request=request)
# now the API class instance knows something about the keys (only within
# the 'api' namespace that the template used...
print api.used_keys # set of keys that the template accessed that were valid
print api.invalid_keys # set of keys the template accessed that were invalid
print api.unused_keys # set of keys valid keys that were not used
现在,请注意,如果您不想在最后进行任何检查,而只是在用户使用无效 key 时抛出异常,则不要将 None
作为 >exc_class
当模板中有错误的 api.key 时,它会抛出一个 APIKeyError
。
因此,希望这会给您一些想法和一些代码的起点。正如我所说,这根本没有经过测试。将其视为伪代码。
当然,这只会保护 API 中的 key 。任何不以 api
开头的 key 在 Django 中的行为都是正常的。但这里的优势在于您只使用自己的代码,而不会因为 Django future 版本的更改而受到破坏。
关于python - 为 Django 模板定义 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49489528/