Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Template display model verbose_names & objects

I need to display several models name & objects in a template

Here is my view

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)
  )

And my template

{% 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 %}

Of course objs._meta.verbose_name doesn't work

Is there a way to access to this verbose name without having to create a function for each model or to assign the value from the view for each model ?

like image 733
Pierre de LESPINAY Avatar asked Sep 15 '11 14:09

Pierre de LESPINAY


4 Answers

For accessing it in your template, you've probably noticed by now that Django doesn't let you use underscore prefixes to access attributes from templates. Thus, the easiest way to access the verbose name for any given object without having to create a model method on each model would be to just create a template tag:

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

Unrelated, but you have a bug in your template, in that you are trying to access the _meta attribute on a queryset instead of an object. So your title line should instead look something like:

{% with objs|first as obj %}
    <div class="title">{% get_verbose_name obj %}</div>
{% endwith %}
like image 175
Spike Avatar answered Nov 16 '22 16:11

Spike


Tag:

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

HTML (year is the name of my field in my model)

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

Thanks to the reference above. Wanted to share what i found in case others where looking for the same solution i found for my situation.

like image 35
GodAlex12 Avatar answered Nov 16 '22 17:11

GodAlex12


In Django 3.x, I found this the simplest method. I usually put all my object utils in one module:

from django import template

register = template.Library()

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

Then in the template:

{{ object_name|verbose_name }}
like image 2
nicorellius Avatar answered Nov 16 '22 18:11

nicorellius


An alternative solution is to subclass your model's 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'

Now you can get the verbose_name from the queryset directly, without the need to iterate over it:

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

If you want to access the verbose_name from a model instance directly, and not from a QuerySet, you'll need to define a property in your model as well:

class SomeModel(models.Model):
    ...

    objects = SomeQuerySet.as_manager()

    class Meta:
        verbose_name = 'Some Model'

    @property
    def verbose_name(self):
        return self._meta.verbose_name
like image 1
Lord Elrond Avatar answered Nov 16 '22 17:11

Lord Elrond