【问题标题】:Django - Template display model verbose_names & objectsDjango - 模板显示模型详细名称和对象
【发布时间】:2011-09-15 14:03:33
【问题描述】:

我需要在模板中显示多个模型名称和对象

这是我的观点

def contents(request):
  """Lists contents"""
  objects = [
    Model1.objects.all(),
    Model2.objects.all(),
    Model3.objects.all(),
    Model4.objects.all(),
  ]
  return render_to_response('content/contents.html', objs
  , context_instance=RequestContext(request)
  )

还有我的模板

{% for objs in objects %}
  <div class="content">
    <div class="title">{{ objs._meta.verbose_name }}</div>
    <ul>
    {% for obj in objs %}
      <li>{{ obj }}</li>
    {% endfor %}
    </ul>
  </div>
{% endfor %}

当然objs._meta.verbose_name 不起作用

有没有一种方法可以访问这个详细的名称,而不必为每个模型创建函数或从视图中为每个模型分配值?

【问题讨论】:

    标签: python django templates


    【解决方案1】:

    为了在模板中访问它,您现在可能已经注意到 Django 不允许您使用下划线前缀来访问模板中的属性。因此,无需在每个模型上创建模型方法即可访问任何给定对象的详细名称的最简单方法是只创建一个模板标签:

    @register.simple_tag 
    def get_verbose_name(object): 
        return object._meta.verbose_name
    

    不相关,但是您的模板中有一个错误,因为您试图访问查询集而不是对象上的 _meta 属性。所以你的标题行应该看起来像这样:

    {% with objs|first as obj %}
        <div class="title">{% get_verbose_name obj %}</div>
    {% endwith %}
    

    【讨论】:

    • 工作。我最终使用了{% get_verbose_name objs.0 %}(如果没有价值,不确定它是否会起作用)。
    • 也许使用过滤器更干净。几乎是一样的实现,但是调用方法看起来更好。类似{{ obj|verbose_name }}{{ obj.0|verbose_name }}
    • +1 @Mandx,我认为你说得对,它看起来更干净。好电话。
    • 我认为最好使用标签中的return queryset.model._meta.verbose_name,queryset是整个resultSet(不是第一行)
    • 我收到'str' object has no attribute '_meta' 错误。 Django 1.7.
    【解决方案2】:

    标签:

    @register.simple_tag
    def get_verbose_name(object, fieldnm): 
      return object._meta.get_field(fieldnm).verbose_name
    

    HTML(年份是我模型中字段的名称)

    <td><label class="control-label text-lg text-info"> {% get_verbose_name object 'year' %} </label></td>
    

    感谢上面的参考。想分享我发现的东西,以防其他人在我的情况下寻找相同的解决方案。

    【讨论】:

      【解决方案3】:

      在 Django 3.x 中,我发现这是最简单的方法。我通常将我所有的对象工具放在一个模块中:

      from django import template
      
      register = template.Library()
      
      @register.filter
      def verbose_name(obj):
          return obj._meta.verbose_name
      

      然后在模板中:

      {{ object_name|verbose_name }}
      

      【讨论】:

        【解决方案4】:

        另一种解决方案是将模型的QuerySet 子类化:

        class SomeQuerySet(models.QuerySet):
            @property
            def verbose_name(self):
                return self.model._meta.verbose_name
        
        class SomeModel(models.Model):
            ...
        
            objects = SomeQuerySet.as_manager()
        
            class Meta:
                verbose_name = 'Some Model'
        

        现在您可以直接从查询集中获取verbose_name,而无需对其进行迭代:

        <h1>{{ objects.verbose_name }}</h1>
        {% for objs in objects %}
        ...
        

        如果您想直接从模型实例访问verbose_name,而不是从QuerySet,您还需要在模型中定义一个属性:

        class SomeModel(models.Model):
            ...
        
            objects = SomeQuerySet.as_manager()
        
            class Meta:
                verbose_name = 'Some Model'
        
            @property
            def verbose_name(self):
                return self._meta.verbose_name
        

        【讨论】:

          猜你喜欢
          • 2011-11-17
          • 2022-06-12
          • 1970-01-01
          • 2011-09-28
          • 2011-12-09
          • 2020-02-02
          • 1970-01-01
          • 2011-08-23
          • 1970-01-01
          相关资源
          最近更新 更多