【问题标题】:Model name of objects in django templatesdjango 模板中对象的模型名称
【发布时间】:2011-09-28 03:16:58
【问题描述】:

有什么方法可以获取 django 模板中任何对象的模型名称。手动的,我们可以通过在模型中定义方法或者使用模板标签来尝试……但是有没有内置的方法呢?

【问题讨论】:

    标签: django django-models django-templates


    【解决方案1】:

    object.__class__.__name__object._meta.object_name 应该为您提供模型类的名称。但是,此不能在模板中使用,因为属性名称以下划线开头。

    没有内置方法可以从模板中获取该值,因此您必须定义一个返回该属性的模型方法,或者对于更通用/可重用的解决方案,使用模板过滤器:

    @register.filter
    def to_class_name(value):
        return value.__class__.__name__
    

    您可以在模板中使用:

    {{ obj | to_class_name }}
    

    【讨论】:

    • 好的..感谢Shawn的回复。我用这种方式,认为可能是某种内置方式!
    • 我认为对它的需求并不普遍,不足以保证内置方法。如果您经常需要它,您可以创建一个实现该方法的抽象类,然后将其用作所有模型的基础。不过就个人而言,我会坚持使用过滤标签。
    • your_app/templatetags目录下添加过滤文件,命名为to_class_name.py。添加过滤器后,您必须重新启动 Django。不要忘记在您的模板中{% load to_class_name %}
    【解决方案2】:

    您不能直接访问类名。做这样的事情:

    {{ object.__class__ }}
    

    将导致TemplateSyntaxError: Variables and attributes may not begin with underscores。 Django 不允许您访问这些属性 - Python 约定意味着它们是隐藏的实现细节,而不是对象 API 的一部分。

    创建一个模板过滤器,然后你可以如下使用它:

    {{ object|model_name_filter }}
    

    创建过滤器非常简单:https://docs.djangoproject.com/en/dev/howto/custom-template-tags/

    【讨论】:

      【解决方案3】:

      Django 为模型选项添加了一个可公开访问的 API,称为 _meta,但您仍然无法访问模板中带有下划线的变量。使用模板过滤器:

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

      在模板中:

      {{ instance|verbose_name }}
      

      我什至喜欢链接 title 过滤器以大写我的模板中的单词:

      {{ instance|verbose_name|title }}
      

      【讨论】:

      • 这导致'str' object has no attribute '_meta'
      • 那么你没有模型实例。您有一个要应用过滤器的 str ,它没有这样的属性。
      【解决方案4】:

      您可以非常轻松地访问页面的内容类型,这样您甚至不需要戳specific

      {% if pub.content_type.app_labeled_name == 'home | publication' %}
          {% include "home/publication.html" with pub=pub.specific %}
      {% endif %}
      

      【讨论】:

        【解决方案5】:

        从 1.2 版本开始,可能是早期的 Django 有一个属性opts 到模板中。属性链接到model._meta 作为证据,您应该look at source code into Github

        用于模板非常简单:{{opts}}{{opts.db_table}}

        【讨论】:

        • 这仅适用于 django-admin。
        【解决方案6】:

        此答案演示了一个实际用例。在我的应用程序中,每个模型在 urls.py 中都有一个名为 name=”-create” 的 generic.CreateView;在需要链接到它的模板中,命名空间/引用为 {% url :-create %}。每个模型都有一个由 /templates//_list.html 渲染的 generic.ListView。我想在每个渲染列表视图的底部包含一个按钮,以链接到相应的创建视图。为了确保多个列表视图的一致性,我想在每个列表视图模板都可以扩展的基本模板中执行此操作。 为此,我需要能够在模板中引用模型名称。我是这样做的。

        $ mkdir <app>/templatetags
        $ touch <app>/templatetags/__init__.py
        $ vi <app>/templatetags/tags.py
        
        from django import template
        register = template.Library()
        # this filter allows any template to reference an instance’s model name as <instance>|class_name
        @register.filter(name="class_name")
        def class_name(instance):
            return instance._meta.model.__name__
        
        $ vi <app>/templates/base_list.html
        
        ~
        {% with name=object_list|first|class_name|lower %}
                <button onclick="location.href='{% url request.resolver_match.app_name|add:':'|add:name|add:'-create' %}';" title="create"><i class="fa fa-plus"></i></button>
        {% endwith  %}
        

        * 将 替换为您自己的名称。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-17
          • 2014-08-20
          • 2020-05-08
          • 2011-07-22
          • 2019-09-06
          • 1970-01-01
          • 2012-05-14
          相关资源
          最近更新 更多