检查 Django 模板中是否存在模板

发布于 2024-11-11 14:11:40 字数 234 浏览 3 评论 0原文

在将模板包含到 Django 模板之前,是否有一种开箱即用的方法来检查模板是否存在?替代方案也是受欢迎的,但其中一些由于特殊情况而行不通。

例如,这是一个稍微不同的问题的答案。这不是我要找的: 如何检查 Django 中是否存在模板?

Is there an out-of-the-box way of checking if a template exists before including it in a Django template? Alternatives are welcome too but some of them would not work due to the particular circumstances.

For example, here's an answer to a slightly different question. This is not what I'm looking for:
How to check if a template exists in Django?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

娜些时光,永不杰束 2024-11-18 14:11:40

假设如果您向其传递错误的模板引用,则 include 不会崩溃,这可能是最好的方法。您的另一种选择是创建一个模板标签,该标签本质上是在您提到的链接中进行检查。

非常基本的实现:

from django import template

register = template.Library()

@register.simple_tag
def template_exists(template_name):
    try:
        django.template.loader.get_template(template_name)
        return "Template exists"
    except template.TemplateDoesNotExist:
        return "Template doesn't exist"

在您的模板中:

{% template_exists 'someapp/sometemplate.html' %}

该标记并不是真正有用,因此您可能希望创建一个实际上向上下文添加变量的标记,然后您可以在 if 语句或其他语句中检查该变量。

Assuming include doesn't blow up if you pass it a bad template reference, that's probably the best way to go. Your other alternative would be to create a template tag that essentially does the checks in the link you mentioned.

Very basic implementation:

from django import template

register = template.Library()

@register.simple_tag
def template_exists(template_name):
    try:
        django.template.loader.get_template(template_name)
        return "Template exists"
    except template.TemplateDoesNotExist:
        return "Template doesn't exist"

In your template:

{% template_exists 'someapp/sometemplate.html' %}

That tag isn't really all that useful, so you'd probably want to create one that actually adds a variable to the context, which you could then check in an if statement or what not.

江心雾 2024-11-18 14:11:40

我遇到了这种情况,试图仅在存在时显示模板,并最终得到以下模板标记解决方案:

仅在存在时包含模板

将以下内容放入 yourapp/templatetags/include_maybe.py

from django import template
from django.template.loader_tags import do_include
from django.template.defaulttags import CommentNode
register = template.Library()

@register.tag('include_maybe')
def do_include_maybe(parser, token):
    "Source: http://stackoverflow.com/a/18951166/15690"
    bits = token.split_contents()
    if len(bits) < 2:
        raise template.TemplateSyntaxError(
            "%r tag takes at least one argument: "
            "the name of the template to be included." % bits[0])

    try:
        silent_node = do_include(parser, token)
    except template.TemplateDoesNotExist:
        # Django < 1.7
        return CommentNode()

    _orig_render = silent_node.render
    def wrapped_render(*args, **kwargs):
        try:
            return _orig_render(*args, **kwargs)
        except template.TemplateDoesNotExist:
            return CommentNode()
    silent_node.render = wrapped_render
    return silent_node

访问它通过在模板顶部添加 {% load include_maybe %} 并在代码中使用 {% include_maybe "my_template_name.html" %} 来从模板中调用。

这种方法有一个很好的副作用,即搭载现有模板包含标记,因此您可以像使用普通 {% include %} 一样传递上下文变量。

根据模板是否存在进行切换

但是,如果模板存在,我希望在嵌入站点上进行一些额外的格式化。我没有编写 {% if_template_exists %} 标记,而是编写了一个过滤器,让您可以使用现有的 {% if %} 标记。

为此,请将以下内容放入yourapp/templatetags/include_maybe.py(或其他内容)中

from django import template
from django.template.defaultfilters import stringfilter


register = template.Library()

@register.filter
@stringfilter
def template_exists(value):
    try:
        template.loader.get_template(value)
        return True
    except template.TemplateDoesNotExist:
        return False

,然后,从您的模板中,您可以执行以下操作:

{% load include_maybe %}

{% if "my_template_name"|template_exists %}
     <div>
         <h1>Notice!</h1>
         <div class="included">
             {% include_maybe "my_template_name" %}
         </div>
     </div>
{% endif %}

使用自定义过滤器相对于使用自定义过滤器的优势自定义标签的优点是您可以执行以下操作:

{% if "my_template_name"|template_exists and user.is_authenticated %}...{% endif %}

而不是使用多个 {% if %} 标签。

请注意,您仍然必须使用 include_maybe

I encountered this trying to display a template only if it exists, and wound up with the following template tag solution:

Include a template only if it exists

Put the following into yourapp/templatetags/include_maybe.py

from django import template
from django.template.loader_tags import do_include
from django.template.defaulttags import CommentNode
register = template.Library()

@register.tag('include_maybe')
def do_include_maybe(parser, token):
    "Source: http://stackoverflow.com/a/18951166/15690"
    bits = token.split_contents()
    if len(bits) < 2:
        raise template.TemplateSyntaxError(
            "%r tag takes at least one argument: "
            "the name of the template to be included." % bits[0])

    try:
        silent_node = do_include(parser, token)
    except template.TemplateDoesNotExist:
        # Django < 1.7
        return CommentNode()

    _orig_render = silent_node.render
    def wrapped_render(*args, **kwargs):
        try:
            return _orig_render(*args, **kwargs)
        except template.TemplateDoesNotExist:
            return CommentNode()
    silent_node.render = wrapped_render
    return silent_node

Access it from your templates by adding {% load include_maybe %} at the top of your template, and using {% include_maybe "my_template_name.html" %} in code.

This approach has the nice side effect of piggy-backing the existing template include tag, so you can pass in context variables in the same way that you can with a plain {% include %}.

Switch based on whether a template exists

However, I wanted some additional formatting on the embedding site if the template existed. Rather than writing an {% if_template_exists %} tag, I wrote a filter that lets you work with the existing {% if %} tag.

To this end, put the following into yourapp/templatetags/include_maybe.py (or something else)

from django import template
from django.template.defaultfilters import stringfilter


register = template.Library()

@register.filter
@stringfilter
def template_exists(value):
    try:
        template.loader.get_template(value)
        return True
    except template.TemplateDoesNotExist:
        return False

And then, from your template, you can do something like:

{% load include_maybe %}

{% if "my_template_name"|template_exists %}
     <div>
         <h1>Notice!</h1>
         <div class="included">
             {% include_maybe "my_template_name" %}
         </div>
     </div>
{% endif %}

The advantage of using a custom filter over using a custom tag is that you can do things like:

{% if "my_template_name"|template_exists and user.is_authenticated %}...{% endif %}

instead of using multiple {% if %} tags.

Note that you still have to use include_maybe.

潜移默化 2024-11-18 14:11:40

我需要有条件地包含模板(如果存在),但我想使用一个变量来存储模板名称,就像使用常规 {% include %} 标记一样。

这是我在 Django 1.7 中使用的解决方案:

from django import template
from django.template.loader_tags import do_include

register = template.Library()


class TryIncludeNode(template.Node):
    """
    A Node that instantiates an IncludeNode but wraps its render() in a
    try/except in case the template doesn't exist.
    """
    def __init__(self, parser, token):
        self.include_node = do_include(parser, token)

    def render(self, context):
        try:
            return self.include_node.render(context)
        except template.TemplateDoesNotExist:
            return ''


@register.tag('try_include')
def try_include(parser, token):
    """
    Include the specified template but only if it exists.
    """
    return TryIncludeNode(parser, token)

在 Django 模板中,可以这样使用:

{% try_include "template-that-might-not-exist.html" %}

或者,如果模板名称位于名为 template_name 的变量中:

{% try_include template_name %}

I needed to conditionally include templates if they exist but I wanted to use a variable to store the template name like you can do with the regular {% include %} tag.

Here's my solution which I've used with Django 1.7:

from django import template
from django.template.loader_tags import do_include

register = template.Library()


class TryIncludeNode(template.Node):
    """
    A Node that instantiates an IncludeNode but wraps its render() in a
    try/except in case the template doesn't exist.
    """
    def __init__(self, parser, token):
        self.include_node = do_include(parser, token)

    def render(self, context):
        try:
            return self.include_node.render(context)
        except template.TemplateDoesNotExist:
            return ''


@register.tag('try_include')
def try_include(parser, token):
    """
    Include the specified template but only if it exists.
    """
    return TryIncludeNode(parser, token)

In a Django template it might be used like this:

{% try_include "template-that-might-not-exist.html" %}

Or, if the template name is in a variable called template_name:

{% try_include template_name %}
话少心凉 2024-11-18 14:11:40

包含接受变量:

{% include template_name %}

这样你就可以在你的视图中进行检查。

include accepts variables:

{% include template_name %}

so you could do the check in your view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文