如何在 Django 模板中执行此操作

Posted

技术标签:

【中文标题】如何在 Django 模板中执行此操作【英文标题】:How to do this in Django templates 【发布时间】:2011-08-10 16:40:01 【问题描述】:

现在这将是一个有点奇怪的用例。也许有人有一些想法。

背景

我正在编写一个 AJAX 密集型网站。事实上,几乎没有任何完整的页面重新加载。这意味着大量模板组合是在客户端完成的。目前我在 jQuery 中使用了一些自己编写的脚本。为了使事情变得相当简单,我只使用变量占位符,例如: somevar.someattr.someotherattr 。我可能可以使用类似小胡子的东西来实现类似的行为。

另一方面,有时我希望能够在服务器端做一些组合。我正在寻找一种方法来避免在客户端和服务器端出现无意义的代码重复。

想法

我希望能够以这样一种方式呈现 Django 模板,即输出中的某些空白将保持不变。更具体地说,如果模板渲染上下文中未提供给定变量,则占位符仍应为 contents 。我想知道使用过滤器和/或标签是否可以实现这种或类似的行为。

我可以写 somevar.someattr|default:" somevar.someattr " ,但这不是很干。

【问题讨论】:

【参考方案1】:

您可以将TEMPLATE_STRING_IF_INVALID 设置为%s

http://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATE_STRING_IF_INVALID

【讨论】:

...但这似乎只是为了调试目的和全局设置,对吧? 这是推荐的,特别是如果您使用其他应用程序,如 Admin。但我发现它不会破坏任何东西。我提到它是因为,它就在那里。您可以选择它对您的影响。 我想我会围绕这个功能使用一些技巧。【参考方案2】:

我不了解 Django,但可能值得一看的是 javascriptMVC:http://javascriptmvc.com/

【讨论】:

这很有趣。然而,尝试使用它实际上会迫使我完全重写应用程序。同样据我了解,这迫使我将应用程序构建为严格的 SOFEA,我还没有准备好这样做。 好吧,我最终没有使用 jmvc,但是你的这句话启发了我对可用的东西进行更深入的研究,我发现了 Backbone.js,从某种意义上说,它有很多常见的。我真的很高兴我找到了它。可能为自己节省了很多时间,所以谢谢你。【参考方案3】:

这就是我最后想到的:

代码:

from django import template

register = template.Library()

@register.filter(name='tmpl')
def tmpl_filter(value, arg=None):
    return value or (" %s " % arg)

@register.tag(name='tmpl')
def tmpl_tag(parser, token):
    nodelist = parser.parse(('endtmpl',))
    parser.delete_first_token()
    return UpperNode(nodelist)

class UpperNode(template.Node):
    def __init__(self, nodelist):
        super(UpperNode, self).__init__()
        self.nodelist = nodelist
        nodes = self.get_nodes_by_type(template.VariableNode)
        for n in nodes:
            v = n.filter_expression.var
            if v.lookups:
                for i, f in enumerate(n.filter_expression.filters):
                    print f
                    if f[0] == tmpl_filter and len(f[1]) == 0:
                        n.filter_expression.filters[i] = \
                            (f[0], [(False, '.'.join(v.lookups))],)

    def render(self, context):
        return self.nodelist.render(context)

用法:

% load placeholders %
% tmpl %
     var.for.template|tmpl 
     regular.var 
    % nestedtag %
         another.var.for.template|tmpl 
    % endnestedtag %
% endtmpl %

这是一种 hack,但不会造成真正的麻烦。我也认为它是线程安全的,但是在这方面还没有测试过。

【讨论】:

【参考方案4】:

这是我在 Django + ICanHaz.js 中使用的。有了这个,您可以使用过滤器或标签: http://tothinkornottothink.com/post/4282971041/using-jquery-templating-icanhaz-js-with-django

【讨论】:

很好,我一定会试试的。 我有一个问题。这也处理导入标签吗?区块扩展呢?

以上是关于如何在 Django 模板中执行此操作的主要内容,如果未能解决你的问题,请参考以下文章

如何在 % % 之间的 Django 模板中使用变量

如何在 django 中生成 url

如何使用 DJango 在 for 循环中使用变量

如何在模板中删除 django URL 中的尾随斜杠?

在django中渲染模板后如何在我的视图中调用一些逻辑

使用 Ajax、Django 将上下文传递到模板中