Regroup vs. IfChanged in Django templates
This might be one of those things that is obvious to everyone but me, but I have a tendency to forget about Django’s regroup functionality. In this particular case, I wanted to make an alphabetical list of page titles, separated by a headline for each letter of the alphabet represented. My first attempt used IfChanged:
[toggle code]
-
<ul>
-
{% for item in page.family %}
- {% ifchanged %}</ul><h2 id="{{item.title|first|upper}}">{{ item.title|first|upper }}</h2><ul>{% endifchanged %}
- <li><a href="{{ item.url }}">{{ item.title }}</a></li>
- {% endfor %}
-
{% for item in page.family %}
- </ul>
I should have realized I was doing something wrong when I had to put in an empty list (before the letter “A”) to make it worked with IfChanged. It only became obvious for me, though, when I tried to add a “top” link at the bottom of each section of the alphabet. IfChanged wasn’t going to be able to handle it, because the letter “A” shouldn’t have a “top” link above it. I could use forloop.first, but then the IfChanged section would change between the first A item and the second A item, resulting in two headlines for the letter A.
I went to the Django template language for template authors page to see if there was a solution; there was (IfChanged can take a variable name) but I noticed regroup and wondered if it might be more appropriate. I’ve used it before, but not with filters. The documentation doesn’t mention using filters with the “by” portion of regroup, but I thought I’d flail around a bit. Turns out it works. If I “regroup page.familyIndex by title|first|upper as letters” I get a listing of each first letter represented in the titles.
[toggle code]
- {% regroup page.family by title|first|upper as letters %}
-
{% for letter in letters %}
- <h2 id="{{ letter.grouper }}">{{ letter.grouper }}</h2>
-
<ul>
-
{% for item in letter.list %}
- <li><a href="{{ item.url }}">{{ item.title }}</a></li>
- {% endfor %}
- <li class="topper"><a href="#top">(top)</a></li>
-
{% for item in letter.list %}
- </ul>
- {% endfor %}
No more empty list and no problem adding a special link at the bottom of each letter of the alphabet.
- Django template language for template authors
- “Django’s template language is designed to strike a balance between power and ease. It’s designed to feel comfortable to those used to working with HTML.”
More Django
- Converting an existing Django model to Django-MPTT
- Using a SQL database to mimic a filesystem will, eventually, create bottlenecks when it comes to traversing the filesystem. One solution is modified preordered tree traversal, which saves the tree structure in an easily-used manner inside the model.
- Two search bookmarklets for Django
- Bookmarklets—JavaScript code in a bookmark—can make working with big Django databases much easier.
- Fixing Django’s feed generator without hacking Django
- It looks like it’s going to be a while before the RSS feed generator in Django is going to get fixed, so I looked into subclassing as a way of getting a working guid in my Django RSS feeds.
- ModelForms and FormViews
- This is just a notice because when I did a search, nothing came up. Don’t use ModelForm with FormView, use UpdateView instead.
- Django: fix_ampersands and abbreviations
- The fix_ampersands filter will miss some cases where ampersands need to be replaced.
- 29 more pages with the topic Django, and other related pages