As a designer, I’m absolutely in love with Django’s template language. It gives me full control over my project’s markup and offers a lot of built-in tools that let me do complex things I haven’t been able to manage with other systems. And, in the case that it doesn’t give you what you need, you can always extend it by writing your own template tags and filters.
But buried deep within the bowels of the existing template tags and filters, Django has a few gems you may not know about, and a few others that can be used in ways you may not have thought of. I thought I’d take a moment to highlight a few of my favorite, more advanced Django template bits.
firstof
Django’s firstof tag is a very simple and very useful one that doesn't get much attention. All it does is display the first available variable from a list you provide. Take, for example, the typical "Welcome, Jeff!" message that you might see at the top of any site you've created an account on. On these types of sites, some people divulge their full name, some people only give up their first name, and some people aren't willing to provide any information. In this case, using the firstof tag can save you a lot of ugly if...then logic, by allowing you to do something like this:
<p>Welcome, {% firstof user.full_name user.first_name user.username %}!</p>
Simple, but very useful.
cycle
The cycle tag is very useful for many purposes, but it's especially handy when you're trying to style every other item differently. For example, maybe you want to add zebra stripes to your tables, or maybe you want every other comment after your blog entry to have a different background color. You can use cycle like so:
{% for row in table_data %}
<tr class="{% cycle 'odd' 'even' %}">
...
</tr>
{% endfor %}
This will result in every other table row having a class of “odd” or “even,” which you can style appropriately using CSS.
dictsort and dictsortreversed
Almost certainly the most fun Django filter to say out loud, dictsort lets you sort a list of objects by an attribute of that object. For example, let's say you have a list of people and each of them have a gender attribute of either "Male" or "Female". If you want to display all the women first and all the men second, you could do something like this:
<ul>
{% for person in people_list|dictsort:"gender" %}
<li>{{ person.full_name }}, {{ person.gender }}</li>
{% endfor %}
</ul>
dictsortreversed works exactly the same way, but reverses the order after sorting (in this case, putting males ahead of females). You can dictsort on any type of attribute, including dates, integers, and strings.
regroup
The regroup tag is one that can be tricky to get your mind around, but is incredibly useful once you do. It regroups a list of items by a like attribute and saves them into a new variable. This variable has "groupers" that let you display the items by group. It's especially useful in combination with dictsort. For example, let's extend our gender list above. Maybe instead of saying "Male" or "Female" on every list item, we'd rather have two separate lists with a header above them stating the gender. Using regroup, we can do just that:
{% regroup people_list|dictsort:"gender" by gender as gender_list %}
{% for gender in gender_list %}
<h3>{{ gender.grouper }}</h3>
<ul>
{% for person in gender.list %}
<li>{{ person.full_name }}</li>
{% endfor %}
</ul>
{% endfor %}
To break that down, our people_list variable is being converted into a separate gender_list variable that contains (in this case) two items: one for male, and one for female. Each of those items has a grouper attribute (the word "Male" or "Female") and a list attribute (the list of people belonging to that group).
widthratio
According to the Django documentation, the widthratio tag, "calculates the ratio of a given value to a maximum value, and then applies that ratio to a constant." Unfortunately, I suck at math, so that doesn't make any sense to me. What does make sense is an example of how this tag can be used to create bar chats and the like. When I worked for the Lawrence Journal-World newspaper, we had daily polls for our readers and used the widthratio tag to display the results as a bar chart. For an example, see this poll. The template code used to create that poll looks something like this:
<table class="poll-results">
<tr>
<th>Response</th>
<th></th>
<th class="numeric">Percent</th>
<th class="numeric">Votes</th>
</tr>
{% for choice in poll_choice_list %}
<tr>
<td>{{ choice.title }}</td>
<td class="bar-graph">
<div class="bar-wrapper">
<div class="bar" style="width: {% widthratio choice.count poll.total_votes 220 %};"></div>
</div>
</td>
<td class="numeric">{% widthratio choice.count poll.total_votes 100 %}%</td>
<td class="numeric">{{ choice.count }}</td>
</tr>
{% endfor %}
</table>
Breaking this down, we pass the widthratio tag the number of times a choice has been voted for, the number of total people voting in the poll, and the number of pixels long each bar is (in this case, 220). In the second usage, we're trying to find the percentage, so we again use widthratio, but simply pass it 100 as the final argument.
Conclusion
These are just a few of the great tags and filters included with the Django distribution. There are many more, as well as hundreds of interesting template bits listed on Django Snippets. The wealth of tags and filters available for Django’s template language combine to make it an incredibly robust and useful tool for any meticulous designer.
What are your favorite Django template tricks?

Oh geez… there he goes with that Django stuff again…
Just kidding, keep it comin’! ;)
Oh man, Jeff, you melted my brain. And saved me dozens of lines of code. Can’t wait to try this stuff. Thanks!
I am not familiar with Django, is this something that could be done in a data model, too? I do the same thing in other languages/frameworks (PHP and CakePHP/Ruby and RoR) and have this taken care of in the model.
Only reason I ask, is that it seems like it would be more DRY to include that in a model, in case you want to do the same thing in other templates.
In rails, I would create an instance method like .screen_name, that method would then decide on the full name, first name, or their login (username). Then, in templates I only have to do something like user.screen_name.
Thoughts? Again - just curious. Django is something I would like to learn more about - so maybe I am just missing something in the translation.
I like using a slug field as an ID on an HTML element.
The slug is generally used for URLs, but I’ve found it to be perfect for elements that need a unique ID to which I can add a hash to create a permalink within a page. I could use the slugify filter, but why bother when I can already use data that’s readily available.
Yes, you certainly could add a method to the model to do the same thing, exactly like your
screennamemethod you describe in Rails. You could do that, and there would be absolutely nothing wrong with doing that.Understanding why something like this is available in the template language and you are not necessarily expected to add it as a model method boils down to a design decision on the Django side: Django was designed with the idea that the template author is an HTML person or designer who is not a programmer. That is to say, they would not ever be touching the models. This echoes the organizational structure we had in Lawrence whereby Python people and HTML people worked on separate parts of the project and rarely crossed-over. In that situation, the trouble with adding it to the model is that if I want it in my design, I would have had to go and ask the programmer to add it to the model. If programmers had to be constantly adding model method to satisfy my design needs, they wouldn’t have been happy. :)
Bottom line is this: presentational logic should be in templates (or views, as other frameworks might call them), not in models or controllers. Business logic should be in models and controllers. If the
screennamemethod is something that is used across the application in many capacities (and it very well may be), then it probably makes sense to add it to the model as a method. If it's just for presentation, then I think it belongs in the template.Maybe another example is on order. What about using
firstoflike this...Say I have a flickr photo object. That object has several different photo URLs; one for each size Flickr provides (square, medium, large). However, not all photos have every URL. If you upload a small photo, it will not have a “large” URL. Maybe I want to display the biggest possible photo:
{% firstof photo.large_url photo.medium_url photo.square_url %}
Or, better yet: what if the variable you want to display the first of aren’t from the same model?
{% firstof photo.title entry.title bookmark.title %}
I do that, too. Great tip! Relatedly, when I build a Django app, I tend to put a SlugField on just about everything, even things I don’t currently foresee myself making a detail page for. It’s useful for stuff like your HTML ID, and I feel like it just future-proofs my app, in case I ever do want a detail page for that object.
nice list. what additional, as in homegrown or snipped, template tags do you use? thx, diN0.
As one of likely several people who responded to your tweet with, “Hey, do something about Django!”, I appreciate this. I’m in the very early stages of learning Python and Django, but I can already see where this would come in handy.
Daniel
Thanks for the response, Jeff. I ask that because most frameworks are similar in the way they handle these types of things. With that being said, I would still ask a few more questions with it. To anyone else reading, this is not to create a Rails vs. Django debate. I am simply asking questions from within the tools that I use to get a clearer picture.
I would agree that this is a necessary separation. As much as I love our designer, I most definitely would not want his hands ever to be in the models. But, this is also where we need to work together. As a designer, he could be creating himself more work by trying to copy/paste that all over the place, only to find out he wanted to do it differently later. Now he has to change all of those.
To branch of for a quick second:
I actually think that any presentational logic should be in HTML helpers or partials. Things that are abstracted from the template that make them more portable and re-usable. I also believe that all business logic should be contained in the models. The controllers simply live to handle the request that was routed to them - and do certain things on date (CRUD). So, I think we agree on this (for the most part). Does Django have something like helpers or partials?
I would say that even with your other examples, I would have still included them in a model. The one that utilizes two models would be connected in a logical way (association or proxy), and then put together there.
To come back to my initial point. I think the programmers and designers need to work together. As a programmer, I am here to help make our designer’s life a little easier and to help him keep our applications neat, tidy, and DRY. Many times, if I see him repeating something like that in a view I will make a model method for him. Then, later, if he wants to change it - he can ask me to update it for him accordingly.
Think of it in other terms. What if you separated the roles like that with someone who does only CSS and someone who does only HTML. They are separate layers. The HTML guy could say “I don’t want to bother the CSS guy with this, so I will just use inline styles to achieve my affect.” We know that wouldn’t be optimal, as you would want your styles living in the CSS sheet. This may be a far fetched example, but the core of it is that you want to eliminate duplication of things. The screen name of a user, to me, most definitely needs to live in the model. It is business logic (how you reference your user), and could potentially be used in many other places in the application (emails, feeds, APIs, etc). Your designer has an easy method (they don’t have to use a helper or partial), and if they choose to change - it’s a quick fix for the programmer. I think it would be a bad situation where the relationship of the designer and programmer was so closed off.
The other methods you showed, I believe, are related directly to the view logic. You have to use something like ‘cycle’ inside of the view, as it is presentational logic.
NOTE: If you deem this as off subject for this post, feel free to remove and we can chat about it via another communication method. I just enjoy the discussion.
Yes, if I understand correctly what “helpers” and “partials” are in the Rails world (and I think I do, but I may not, because i’ve never used Rails). Django calls them Template Tags.
And you would be more than welcome to do it that way in Django, if you wanted. But again, keep in mind that not all Django template authors have access or permission to change Django models. Django is very popular in the journalism world, and many newspapers employ template authors which are simply not qualified to be mucking around in Python code.
Similarly, apps are not always written by the people using them. For example, I use django-tagging, a third-party app that provides tagging functionality to other Django apps. I’m not going to add model methods to it, because doing so would break the updatability/maintainability of the app.
Or, to use the
screennameexample: Django comes with a built in Users model, and it doesn't include ascreennamemethod. Maybe it should. But it doesn't. So what am I to do?My point is this: we are in total agreement on the right way to do things, but pretending like it’s possible to always do things exactly the right way is not practical.
I agree that’s how it should work, but I think we can all agree that it doesn’t always work that way in the real world. Clearly, we need to keep things as DRY as possible. If you’ve got an model that is clearly going to need a
screennamemethod, then by all means, make that model method. On the other hand, if you're writing an app that is going to be in in 500 installations and only one of them is going to need to do this sort ofscreennamelogic, then I see no problem with it being done in the template (which other frameworks would call a view).I don’t really agree. I use inline styles all the time. There’s a time and a place for them, just like there’s a time and place for something like
firstof.Absolutely. But how does the
firstoftag encourage duplication?We agree on that. Like I said, maybe it was a bad example.
Bad? Maybe. But it happens all the time. In Lawrence, we sold Ellington to hundreds of newspaper clients. When those newspaper clients went to build their templates, they didn’t have access to the developers who wrote Ellington to ask for a method to be added to a model, just like you don’t have access to get Apple to add some hook to iTunes you want. Same thing.
Well, if you deem
firstofto be inappropriate, you never have to use it. :) Frankly, I find it incredibly useful, so I'm going to keep using it.Ahh, I understand. This makes more sense of knowing where it is used. So at this point then, Django (or whatever the app name) builds the CMS. It is handed over to clients for use, but they don’t have actual control over the code, such as you would with direct access to the Framework.
This parallels with Rails use of plugins. Now, again, this comes back to me not knowing enough about Django (but wanting to learn). In rails I can override methods at runtime and at different points in my application. If I use a third-party plugin, I can alter some of it’s uses by having a proxy layer in the middle that translates it for my needs. Updates to the plugin are not interrupted, I just hook into their API and modify as is deemed necessary. Is this possible to do with Django? Just wondering about how you can extend the framework if necessary (if you can even define it as a framework).
I guess I am more confused about what Django is, so I apologize for my questions that may seem elementary. You get preset models already setup with Django? What if I don’t need a users model?
Agreed. I know now all situations are the same. I was just looking at one method that stuck out to me.
Right, I understand. I would consider myself a pragmatist as well - this was a poor example on my end. Just trying to parallel it with the design aspect of keeping things DRY and clean. I was looking at it as: inline styles are necessary, especially when the application needs to do math for positioning of things, whereas if you find yourself repeating the same inline styles over and over again - then that is a sure sign that there is a better way to manage them.
You are applying a method, firstof, to different variables. You mentioned using it in the header of your files, but what if it had to be used in other places? Wht if you used it in a sidebar for account information for some reason? What if you used it in a paragraph of content? There are many other places it could be used. We use something like this, but in any given admin interface there are many areas where this is used. Top of the page for account and CTA. In their own account page. Inside of content pages when referencing who the page/blog/photo/video was created by. Both the front end and back end administration.
If it’s only being used once, I can understand. Also, in Rails, our models could have different naming conventions, there are no models out of the box - you create them. So putting this in a view is assuming the DB schema would never change for whatever reason. Again, what would happen if down the road something else was changed and this method needed to pull from a profile table or some other spot. Do you go back and change all of them, or let that business logic live in the model and access it directly in your templates, views, partials, helpers, etc.
For example, In rails I could do the same thing by specifying the fields with an ‘equals or’ operator that will use whatever fits the bill. This is all well and good, but it assumes the naming conventions stay the same and the business logic needs will never change.
I may just email you some of the example so I don’t mess up the markdown syntax of things.
Well, I have never used Django, I just see you as an authoritative voice on the subject and enjoy the dialogue. Thanks again for the clarifications.
Short answer: yes. You can override pretty much anything at any point.
Well, I wasn’t very clear. Let me back up. Django itself does not include any pre-setup models.
Django apps (usually) have models. In most cases, Django “apps” are designed to be small pieces of code that do one thing and do it well. They are intended to be as generic as possible, such that they can plug-and-play with other apps. For example, an app might provide tagging functionality (tools that let any object from any model in any app be tagged). Another app might provide commenting functionality (tools that let any object from any model in any app be commented upon). Yet another might provide syndication tools (tools that let you build an RSS/Atom feed of objects from any model in any app).
So, with that out of the way: the Django distribution includes what are called “contrib” apps. They’re a set of pre-created apps that provide common functionality that many sites need. For example, there is a comments app. And a syndication app. And an auto-generated admin interface app. And so forth. All of these are completely optional. Another contrib app distributed with Django is called “Auth,” and it provides Users and Groups functionality. Like I said, it’s totally optional. If you don’t need Users and Groups, you don’t use it. If you need Users and Groups but you don’t like the contrib app that comes with the Django distribution, you can still write your own, instead.
So, when I referred to Django’s User model, I really meant the User model of the contrib app that comes with Django, which I (and most Django programmers) tend to use. :)
Sorry for the confusion.
If it had to be used it other places, I’d write the code once and then pull it into each of those places (Django templates provides includes, and better yet, and extension mechanism to keep things super DRY).
Well, I would only have to change one of them (as I said, I would only write the code once. I’m super anal about being DRY). But, more to the point: I agree that it being in the model is a better place for it, for all the reasons you’re stating. I’m just saying that in the Django world, there are many circumstances where the person writing the templates has no access to the models, for whatever reason (maybe it’s a third-party app, maybe they’re simply not “allowed” to change the models because it’s not their job).
Same for me. I’ve never used Rails, so it’s always hard for me to discuss Django as it compares to Rails. I don’t really know the Rails terminology, and what is similar and what is different. In that sense, I’m really not a very authoritative voice on the matter. I can tell you about Django, but when people say, “Rails has helpers, does Django?,” I get lost. :)
But, I enjoy the dialogue, as well! Thanks for participating. :)