Django - 模板对象如何访问 verbose name

14

我有一个名为Scrib的模型和一个模板,其中Scrib.objects.all()被存储到scribs中。

在模板中,我想访问模型的可读名称,例如:

<h1>{{ scribs.model.verbose_name }}</h1>

是否可能,或者我必须将Scrib处理程序添加到上下文中?

3个回答

11

您无法直接从模板访问verbose_name。根据我所看到的,有三个选项。

第一种选择(最简单的方法)。在控制器中分配verbose name,然后从模板中访问它:

# in controller
render_to_response('template.html', {'scrib_verbose_name': Scrib._meta.verbose_name})

# in a view template.html
Verbose name of a Scrib model: {{ scrib_verbose_name }}

选项二:编写一个视图助手,它将返回给定类的verbose_name(或_meta类的其他字段)。

更新第三个选项(致敬Uku Loskit) - 在scrib模型上定义一个方法,该方法返回元对象(或其中任何特定字段)。

# method in a Scrib model
def meta(self):
    return self._meta

# later on in a template - scrib is a instance of Scrib model
<h1>{{ scrib.meta.verbose_name }}</h1>

更新2 如果您坚持直接访问scribs中的verbose name(它是Scrib.objects.all()的结果),那么您可以使用以下方法:

scribs = Scrib.objects.all()
scribs.verbose_name = Scrib._meta.verbose_name

# in a template you can now access verbose name from a scribs variable
{{ scribs.verbose_name }}

更新3 另一种方法是使用模型继承,以便能够从任何继承我们自定义模型的实例中访问显示名称。

# base model (inherits from models.Model)
class CustomModel(models.Model):
    def meta(self):
        return self._meta

    class Meta:
        abstract = True

# Scrib now inherit from CustomModel
class Scrib(CustomModel):
    # do any stuff you want here ...

Scrib现在继承自CustomModel类,它为我们提供了meta属性。任何继承自CustomModel类的模型都将具有此属性。这是最清晰和最灵活的解决方案。


实际上,scribs 等同于 Scrib.objects.all(),因此它是一个多个对象。我是否需要将 Scrib 替换为 Scrib.objects.all() 放入 scribs 中? - Pierre de LESPINAY
如果您在模板中循环遍历scribs,那么您可以在循环中的每个scrib实例上使用.meta.verbose_name。如果您想要仅显示一次(例如在实际循环之前),则可以使用{{ scribs.0.meta.verbose_name }}来显示使用scribs数组中的第一个scrib的verbose name。 - WTK
你可能把事情搞得太复杂了,或者我只是不明白你想要什么 :) 无论如何 - 我已经再次更新了我的答案。 - WTK
好的,我的答案中又有一个解决方案——这次是使用模型继承来提供对任何模型的元数据访问。请记住,从我所理解的情况来看,您正在尝试从 QuerySet 对象(基本上是这些模型的列表)中访问保留给模型类的信息。在我看来,最好直接从模型中保留并检索此信息。 - WTK
我喜欢更新(第三个解决方案)。一旦我想到它,就显而易见了。干得好。 - tatlar
显示剩余3条评论

8

我也希望能做到这一点,我想另一个解决方案可能是使用模板过滤器:

from django import template
register = template.Library()

@register.filter
def verbose_name(value):
    return value._meta.verbose_name

@register.filter
def verbose_name_plural(value):
    return value._meta.verbose_name_plural

然后在模板中:

1 {{ object|verbose_name }}, 2 {{ object|verbose_name_plural }}

1 scrib, 2 scribs

2
在Django 3.0中,这似乎会导致“'str' object has no attribute '_meta'”错误。 - alias51

6

除了WTK的建议,你还可以在models.py中为Scrib模型定义一个方法,如下所示:

def get_verbose_name(self):
    return self._meta.verbose_name
# in templates
{{ scrib_instance.get_verbose_name }}

我是否需要为所有需要详细名称的对象创建此方法,还是有更简单的方法? - Pierre de LESPINAY
1
@PierredeLESPINAY 你可以创建一个基础抽象模型,然后让所有的模型都继承它。只需编写一次,随处使用。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接