Accessing a model’s verbose names in Django templates

I love building web applications with Django and I love its ORM. Defining models is fairly simple and rendering forms and list is (more or less) straight forward.

However, if you want to access the properties of the model’s fields in templates, then you might find a dead end really fast. This is especially hard when you’re trying to access the verbose names of the model or its fields.

Example

The model

As mentioned before, defining models is quite simple. Here’s an example of a model:

As you can see, a  Host has a hostname and an os field.

The list view

Now let’s say we want to display a list of hosts.

First of all we need our ListView:

And of course our host_list.html template, which is something like:

The problem

This is how I’ve defined my ListViews in the past. Of course this works and there’s no problem with it, except for one little and probably important thing:

We’ve already defined verbose name of the model and its field in the model definition, for example the os field:

In our template we had to define and translate the exactly same strings again, for example:

Sure this would work fine, but this isn’t very nice and doesn’t meet my DRY expectations. This problem occurs only when we’re using ListViews or DetailViews. As soon as we’re using Forms, we no longer have these problems, as forms already access the verbose names out of the box.

I had to change a lot of verbose names lately. Unfortunately I’ve defined all the table headers manually as described above, so eventually I had to search and replace all the occurences in the templates by hand. To be honest, I’m not a big fan of repetetive tasks and I was going nuts.

The solution

I came up with a solution, because I thought there must be a better way to deal with this kind of problem.

Adding the model to the context data

First of all I’ve added the model to the context data to all of my ListView instances. I didn’t want to repeat myself, so I created a new ListView class inherited from Django’s ListView:

Then I’ve updated all my existing view modules by importing my ListView instead of the origin Django ListView:

Of course you can also go for method decorators, but in this case you always have to define get_context_data() in your views just to decorate them.

Adding template tags

Now as I had access to the models in all my list templates, I was going to create some template tags:

I saved them as model_name.py.

Accessing the verbose names in templates

Now I finally used the magic sauce I’ve put together:

As you can see with the load of model_name and the model itself, you can now get the model and field names by using:

Conclusion

Adding the model to the ListView context is a clean way to access the model’s and fields verbose names in list views. By accessing the existing model and field properties, you can define the verbose names in one single place – the model definition.

You don’t necessary need the template tags, as you can now access the model’s attributes directly in the template itself. However, using template tags is more convenient and you can now add some additional logic to the tags (e.g. fallback to the name when no verbose name is defined).

 

Leave a Reply

Your email address will not be published. Required fields are marked *