为Django-Templates定义API?

时间:2018-03-26 10:42:31

标签: python django api django-templates

我认为模板可以与方法相媲美。

IPO(输入 - 处理 - 输出):

  1. 需要一些输入。
  2. 进行一些处理
  3. 它输出了一些东西。最有可能是HTML。
  4. 在Python中,方法具有必需和可选参数(使用默认值)。

    有没有办法为Django-templates定义(我称之为)API?

    • 我想要一些参数。
    • 我想要一些参数来设置默认值。

    使用案例:客户可以通过Web界面编辑模板。我想告诉客户模板的更改是否有效。

    我可以渲染模板,看看是否发生错误,但这不包括这种情况:

    模板应该呈现值" foo_needs_to_get_rendered"。

    在这种情况下,通过渲染(并丢弃结果)来验证模板不会显示错误。

    相关:我想向客户展示编辑模板的帮助信息。我想列出上下文的所有可用变量。示例:"您可以使用以下变量:{{foo}},{{bar}},{{blue}} ..."

2 个答案:

答案 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_defaultrequired <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 ''