ich konfrontiert kürzlich die gleichen Rätsel, und nach dem {% if %}
-Tag in den Weg suchen, hier ist strukturiert ist, was ich kam mit:
from django.template.base import VariableDoesNotExist
from django.template.defaulttags import IfNode
from django.template.smartif import IfParser, Literal
# Used as a value for ifdef and ifndef tags
undefined = object()
class IfDefLiteral(Literal):
def eval(self, context):
if not self.value in context:
# Can't raise an exception here because Operator catches it
return undefined
class IfDefParser(IfParser):
def create_var(self, value):
return IfDefLiteral(value)
class IfDefNode(IfNode):
def __init__(self, defined=True, *args, **kwargs):
self.defined = defined
super(IfDefNode, self).__init__(*args, **kwargs)
def __repr__(self):
return "<%s>" % self.__class__.__name__
def render(self, context):
for condition, nodelist in self.conditions_nodelists:
match = undefined
if condition is not None: # if/elif clause
try:
match = condition.eval(context)
except VariableDoesNotExist:
pass
if condition is None or ( # else clause, always render
(self.defined and match is not undefined) or
(match is undefined and not self.defined)):
return nodelist.render(context)
return ''
def _gen_ifdef(parser, token, block_tokens, defined):
# {% if ... %}
bits = token.split_contents()[1:]
condition = IfDefParser(bits).parse()
nodelist = parser.parse(block_tokens)
conditions_nodelists = [(condition, nodelist)]
token = parser.next_token()
# {% elif ... %} (repeatable)
while token.contents.startswith(block_tokens[0]):
bits = token.split_contents()[1:]
condition = IfDefParser(bits).parse()
nodelist = parser.parse(block_tokens)
conditions_nodelists.append((condition, nodelist))
token = parser.next_token()
# {% else %} (optional)
if token.contents == 'else':
nodelist = parser.parse(block_tokens[-1:])
conditions_nodelists.append((None, nodelist))
token = parser.next_token()
# {% endif %}
assert token.contents == block_tokens[-1]
return IfDefNode(defined, conditions_nodelists)
@register.tag
def ifdef(parser, token):
"""Check if variable is defined in the context
Unlike the {% if %} tag, this renders the block if the variable(s)
exist within the context, not only if they are truthy. That is, variables
with None, 0 or [] values would also render the block.
"""
return _gen_ifdef(parser, token, ('elifdef', 'else', 'endifdef'), True)
@register.tag
def ifndef(parser, token):
"""Check if variable is *not* defined in the context
This is the opposite of {% ifdef %}.
"""
return _gen_ifdef(parser, token, ('elifndef', 'else', 'endifndef'), False)
Dann würden Sie es wie ein {% if %}
Tag in Ihrer Vorlage verwenden:
{% ifdef letters or numbers %}
{# do something with letters or numbers #}
{% else %}
{# variables are not defined here #}
{% endifdef %}
Ich bin mir nicht sicher, ob es einen einfacheren Weg gibt, dies zu erreichen, und obwohl ich mit dem Ansatz nicht allzu glücklich bin, scheint es in meinem Anwendungsfall gut zu funktionieren. Hoffe das hilft!
danke! Ich denke, das ist die sauberste von vielen unsauberen Lösungen. – sha