在 Django 模板中使用 abc.ABC class 对象:为什么 Django 会尝试实例化它?

Using an abc.ABC class object in a Django template: why Django tries to instantiate it?

我想在 Django 模板中使用 abc.ABC 抽象 class 对象(不是实例)。在这些 classes 中,我有几个 class 方法(用 @class 方法装饰器定义),我想用它们来显示信息。

当我尝试显示列表对象时:{{ dataset.provided_services }}

我得到显示的 class 个对象的列表:

[<class 'dataset_services.table_service.QueryTableService'>, <class 'dataset_services.table_service.ExportTableService'>]

但如果我尝试遍历此列表:

<ul>
     {% for service in dataset.provided_services %}
     <li>
         <p>{{ service.name }}</p>
         <p>{{ service.description }}</p>
     </li>
     {% endfor %}
 </ul>

我收到一条错误消息,告诉我无法使用抽象方法实例化抽象基础 class,就像 Django 试图实例化 class 对象一样...这是正常行为吗?是否可以在 Django 模板中使用 class 个对象而不实例化它们?

PS: 我正在使用 Django 1.8.5 和 Python 3.4.

默认情况下,如果 django 模板引擎检测到您正在使用的变量是可调用的,它将在访问子属性之前调用它。这在你想要一个函数的结果(django 不允许你显式调用)的情况下很方便。如果您不想在 django 模板中调用特定的可调用对象,您可以在对象上将标志 do_not_call_in_templates 设置为 True。在你的情况下,你可能想在你的基地 class 上这样做,所以每个 subclass 也有这个属性。

长话短说: 设置 abc.ABC.do_not_call_in_templates = True

有关 django 模板语言如何处理变量的完整文档以及有关 do_not_call_in_templates flag 的更多信息,请参阅 django documentation