मैं हाल ही में एक ही पहेली का सामना करना पड़ा, और जिस तरह {% if %}
टैग यहाँ संरचित है में देखने के बाद क्या मैं के साथ आया था:
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)
तो आप इसे अपने टेम्पलेट में एक {% if %}
टैग की तरह का प्रयोग करेंगे:
{% ifdef letters or numbers %}
{# do something with letters or numbers #}
{% else %}
{# variables are not defined here #}
{% endifdef %}
मुझे यकीन नहीं है कि इसे पूरा करने का एक आसान तरीका है, और जब मैं दृष्टिकोण से बहुत खुश नहीं हूं, तो यह मेरे उपयोग के मामले में अच्छी तरह से काम करता प्रतीत होता है। उम्मीद है की यह मदद करेगा!
धन्यवाद! मुझे लगता है कि यह कई अशुद्ध समाधानों का सबसे साफ है। – sha