gpt4 book ai didi

django 检查模板上下文变量是否存在

转载 作者:行者123 更新时间:2023-12-04 20:11:14 25 4
gpt4 key购买 nike

我正在写一个 django 模板,我想区分 存在上下文变量 vs 它是 None、空等。我已经完成了我的作业,这似乎非常困难。具体来说,这就是我想要做的

view 1:
...
if some_condition = True:
context['letters'] = ['a', 'b', 'c'] # The list might also be empty or None in some cases
else
context['numbers'] = [1, 2, 3] #This list might be empty or None in some cases

Template
...
<ul>
{% if letters %}
{% for x in letter %}
<li>{{x}}</li>
{%endfor%}
{% else %}
{%for x in numbers%}
<li>{{x}}</li>
{%endfor%}
</ul>

使用 {% if %}很冒险,因为如果 letters 会失败不存在或列表为空。我想用 letters即使它是空的(但在上下文中定义)

我对内置过滤器有同样的问题 defaultdefault_if_none如何区分上下文变量的存在与其他事物(如 None 或 Empty)

最佳答案

我最近遇到了同样的难题,在查看了 {% 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 %}

我不确定是否有更简单的方法来实现这一点,虽然我对这种方法不太满意,但它似乎在我的用例中运行良好。希望这可以帮助!

关于django 检查模板上下文变量是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17051073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com