Python 如何访问Django模板中的枚举类型
我遇到了一个问题,无论我做什么,我都无法访问Django模板中的IntEnum(来自enum34库) 通过将其转换为dict,我可以绕过它:Python 如何访问Django模板中的枚举类型,python,django,enums,django-templates,Python,Django,Enums,Django Templates,我遇到了一个问题,无论我做什么,我都无法访问Django模板中的IntEnum(来自enum34库) 通过将其转换为dict,我可以绕过它: def get_context_data(self, **kwargs): context = super(MyView, self).get_context_data(**kwargs) # Django templates don't play nice with Enums context['DEMOS'] = {d.name
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
# Django templates don't play nice with Enums
context['DEMOS'] = {d.name: d for d in DEMOS}
# `context['DEMOS'] = DEMOS` doesn't work
return context
{{ DEMO.FOO }} # outputs nothing
{{ DEMO.FOO|default_if_none:'foo' }} # outputs nothing
{{ DEMO.FOO.value }} # outputs nothing
{% if DEMO.FOO == 1 %} # no matter what I compare to, always False
当DEMO是IntEnum时,这些命令不起作用,但当DEMO转换为dict时,这些命令起作用:
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
# Django templates don't play nice with Enums
context['DEMOS'] = {d.name: d for d in DEMOS}
# `context['DEMOS'] = DEMOS` doesn't work
return context
{{ DEMO.FOO }} # outputs nothing
{{ DEMO.FOO|default_if_none:'foo' }} # outputs nothing
{{ DEMO.FOO.value }} # outputs nothing
{% if DEMO.FOO == 1 %} # no matter what I compare to, always False
你知道为什么吗?这是一个已知的问题吗?再深入一点,我找到了答案 发件人: 从技术上讲,当模板系统遇到点时,它会按以下顺序尝试查找: 查字典 属性或方法查找 数字索引查找 如果结果值是可调用的,则调用时不带参数。调用的结果将成为模板值 最后一行应该是: 如果任何结果/中间值都是可调用的 在这一过程中:
- 在
上下文中查找
,获取'DEMOS'
- 检查它是否可调用(它是)
- 不带任何参数地调用它
- 获取一个
TypeError
枚举
类是可调用的,模板系统将尝试调用它,这将引发错误并中止(返回空字符串:'
)
然而,有一种方法可以解决这个问题。
django.templates.base
的调用代码包含以下内容
防护条件:
if getattr(current, 'do_not_call_in_templates', False):
pass
代码检查模板中名为do\u not\u call\u的属性,如果True
,它将跳过调用部分,这将解决问题
使用Python的Enum
(或最简单的方法)最简单的方法是使用装饰器。如果Django还没有用于此目的的,您可以轻松地推出自己的:
def forDjango(cls):
cls.do_not_call_in_templates = True
return cls
然后装饰您的Enum
:
@forDjango
class DEMOS(Enum):
eggs = 'runny'
spam = 'hard'
cheese = 'smelly'
附加属性不会干扰您的属性集
枚举常量,因为枚举一经定义就固定了。使用Django的Enum
可以使用\uuuu成员\uuuu
属性:
context['DEMOS'] = DEMOS.__members__
@EthanFurman如果您想演示.eggs.name
?Django似乎试图调用下一个
?不要介意前面的问题,它会按预期工作。谢谢你的回答。