我认为模板可以与方法相媲美。
它IPO(输入 - 处理 - 输出):
在Python中,方法具有必需和可选参数(使用默认值)。
有没有办法为Django-templates定义(我称之为)API?
使用案例:客户可以通过Web界面编辑模板。我想告诉客户模板的更改是否有效。
我可以渲染模板,看看是否发生错误,但这不包括这种情况:
模板应该呈现值" foo_needs_to_get_rendered"。
在这种情况下,通过渲染(并丢弃结果)来验证模板不会显示错误。
相关:我想向客户展示编辑模板的帮助信息。我想列出上下文的所有可用变量。示例:"您可以使用以下变量:{{foo}},{{bar}},{{blue}} ..."
答案 0 :(得分:2)
Django模板首先在if (player1Turn) {
((Button) v).setText("X");
((Button) v).setTextColor(Color.parseColor("#0000ff"));
} else {
((Button) v).setText("O");
((Button) v).setTextColor(Color.parseColor("#ff0000"));
}
对象中查找一个键(这是一种dict)。如果密钥不存在,则会引发var arr = [['red','blue','pink'],['dog','cat','bird'],['loud', 'quiet']];
function permutations (fullArray, innerArray) {
return fullArray.reduce(traverseInner, []);
function traverseInner (list, currentText) {
console.log(list, currentText);
return list.concat(innerArray.map(append));
function append (additionalText) {
return `${currentText} ${additionalText}`;
}
}
}
var res = arr.reduce(permutations);
console.log(res);
,它被模板引擎捕获..通常,密钥将呈现为空白。
所以在我看来,如果你想绕过这种行为,你需要让一个缺失的键引发除KeyError之外的其他东西。或者,您可以在模板引擎执行之前捕获Context
,并在重新引发之前保存该信息。
你可以通过继承KeyError
来做到这一点,这需要对模板引擎代码进行一些研究......但这可能是一个非常好的方法。但是你也可以将你的API包装在一个特殊的类中,然后将它放在上下文中。以下代码尚未经过测试..将其视为伪代码,您可以将其作为起点......
KeyError
那么你会检查你的模板:
Context
现在,请注意,如果您不希望在结尾处进行任何检查,但只有在用户使用无效密钥时才会引发异常,那么请不要将# 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()))
作为{{0}}传递给{ {1}}当模板中出现错误的api.key时,它会抛出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
。
所以,希望这会给你一些想法和一些代码的起点..正如我所说的那样,根本没有经过测试......把它想象成伪代码。
当然,这只会保护API中的密钥..任何不以None
开头的密钥都会像Django一样正常。但是,这里的优势在于您只需使用自己的代码,而不会因为未来Django版本的更改而受到破坏。
答案 1 :(得分:1)
它进行IPO(输入处理 - 输出):
我开始学习Django时有同样的想法。下面是我当时每个模板的第一行。最初的目的是在我想调试模板时显示输入值,方法是删除第一行中的{% comment %}
。
{# This comment is to let vim know this is django html template. #}{% comment %}
Purpose: Generate inline add form for intercoolerjs to update single page view.
Input: show_add_form: {{ show_add_form }}, list_path: {{ list_path }}, detail_id: {{ detail_id }}{% if show_add_form %}, default_desc: {{ default_desc }}{% else %}{% endif %}
{% comment %}{% endcomment %}
因此,为了定义API,我认为我们可以从这个模板头开始。然后,您的代码可以在生成的模板中查找doc_string和ValueError。
{% comment %}
doc_string: You can use these variables: {{foo}}, {{bar}}, {{blue}} (default is yellow) ..
{% comment %}{% endcomment %}
{% load my_tags %}
{% required foo 'foo_needs_to_get_rendered' %}
{% required bar 'bar_needs_to_get_rendered' %}
{% set_with_default blue 'yellow' as blue %}
set_with_default
和required
<your app>/templatetags/my_tags.py
custom tags per document。{/ p>
from django import template
register = template.Library()
@register.simple_tag
def set_with_default(value, default=''):
if value:
pass
else:
return default
return value
@register.simple_tag
def required(value, message):
if value:
pass
else:
return 'ValueError: "%s"' % message
return ''