Я столкнулся с этим, пытаясь отобразить шаблон только в том случае, если он существует, и завелся следующим решением тега шаблона:
Включить шаблон, только если он существует
Поместите следующее в 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 шаблона, так что вы можете передавать контекстные переменные так же, как и с простым {% 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
.