【问题标题】:Django - Template objects access verbose nameDjango - 模板对象访问详细名称
【发布时间】:2011-11-17 14:54:19
【问题描述】:

我有一个Scrib 模型和一个将Scrib.objects.all() 存储到scribs 中的模板

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

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

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

【问题讨论】:

    标签: html django templates


    【解决方案1】:

    您不能直接从模板访问 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 }}
    

    选项二:为自己编写一个视图助手,它将返回给定类的详细名称(或 _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>
    

    Update2如果您坚持直接从scribs 访问详细名称(这是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 }}
    

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

    # 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 现在继承自为我们提供属性 meta 的 CustomModel。从 CustomModel 类继承的任何模型都将具有此属性。这是最干净、最灵活的解决方案。

    【讨论】:

    • 实际上scribs 等于Scrib.objects.all() 所以它是一个多对象。我是否必须将Scrib 而不是Scrib.objects.all() 放入scribs 中?
    • 好吧,如果您通过 scribs 在模板中循环,那么您可以在循环中的每个 scrib 实例上使用 .meta.verbose_name。如果您只想显示一次(例如在实际循环之前),您可以简单地使用{{ scribs.0.meta.verbose_name }} 来使用 scribs 数组中的第一个 scrib 显示详细名称。
    • 我不能直接将模型Scrib 放入scribs,循环通过scribs.objects.all 并使用scribs.verbose_name 或更简单的方法吗?否则我必须把这个功能放在我所有的模型上吗?
    • 你把事情复杂化了,或者我只是没有得到你想要的:)无论如何 - 我已经再次更新了我的答案
    • 我正在尝试一些可维护的东西。如果我使用scribs.verbose_name = Scrib._meta.verbose_name,它会将问题推向视图。每次我需要访问详细名称时,我都会在某处进行修改。但如果没有其他办法,我会这样做。
    【解决方案2】:

    我也想这样做,我想另一种解决方案是模板过滤器:

    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
    

    【讨论】:

    • 这似乎导致 Django 3.0 中的 'str' object has no attribute '_meta'
    【解决方案3】:

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

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

    【讨论】:

    • 我必须为所有需要详细名称的对象创建此方法还是有更简单的方法?
    • @PierredeLESPINAY 您可以拥有一个基本抽象模型,并让您的所有模型都从它扩展。一次编写,全部使用。
    猜你喜欢
    • 1970-01-01
    • 2011-12-09
    • 2011-01-26
    • 1970-01-01
    • 2013-01-07
    • 2023-03-28
    • 1970-01-01
    • 2022-06-12
    相关资源
    最近更新 更多