gpt4 book ai didi

python - 如何访问 Django 模板中的枚举类型

转载 作者:太空狗 更新时间:2023-10-29 20:15:23 27 4
gpt4 key购买 nike

我遇到了一个问题,无论我做了什么,我都无法访问我的 Django 模板中的 IntEnum(来自 enum34 库)。

我可以通过将其转换为字典来绕过它:

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 是一个 IntEnum 时,这些不起作用,但当 DEMO 转换为字典时,它们起作用:

{{ 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

有什么想法吗?这是一个已知问题吗?

最佳答案

再深入一点,我找到了答案。

来自 Django's templates documentation :

Technically, when the template system encounters a dot, it tries the following lookups, in this order:

Dictionary lookup

Attribute or method lookup

Numeric index lookup

If the resulting value is callable, it is called with no arguments. The result of the call becomes the template value.

最后一行应该说:

If any of the resulting/intermediate values is callable, ...

逐步完成该过程:

  • 查找 'DEMOS'context , 得到 <enum 'DEMOS'>

  • 检查它是否可调用(它是)

  • 不带参数调用

  • 得到 TypeError

所以问题是 Enum类是可调用的,模板系统将尝试调用它,这将引发错误并中止(返回空字符串:'')。

但是,有一种方法可以解决这个问题。 django.templates.base的调用代码包含以下内容守卫条件:

if getattr(current, 'do_not_call_in_templates', False):
pass

代码检查名为 do_not_call_in_templates 的属性, 如果 True然后它将跳过调用部分,这应该可以解决问题。

使用 Python 的 Enum (或 enum34 backport )最简单的方法是使用装饰器。如果 Django 还没有用于此目的的工具,您可以轻松地自己动手:

def forDjango(cls):
cls.do_not_call_in_templates = True
return cls

然后装饰你的Enum :

@forDjango
class DEMOS(Enum):
eggs = 'runny'
spam = 'hard'
cheese = 'smelly'

附加属性不会干扰你的集合枚举常量,因为枚举一旦定义就固定了。

关于python - 如何访问 Django 模板中的枚举类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35953132/

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