views:

280

answers:

4

I'm relatively new to Django and I'm trying to build up my toolbox for future projects. In my last project, when a built-in template tag didn't do quite what I needed, I would make a mangled mess of the template to shoe-horn in the feature. I later would find a template tag that would have saved me time and ugly code.

So what are some useful template tags that doesn't come built into Django?

+3  A: 

smart-if. Allows normal if x > y constructs in templates, among other things.

A better if tag is now part of Django 1.2 (see the release notes), which is scheduled for release on March 9th 2010.

Daniel Roseman
"Almost certainly will be built in to the next version", are you sure? Everything I've read about template tags being more powerful has been met will string opposition from all the devs. Do you have a link?
nbv4
For the most part you're right, but the particular decision not to allow proper comparisons in `if` tags has been recognised as a mistake (for example in Simon Willison's talk at EuroDjangoCon 09). It's certainly proposed here for 1.2: http://code.djangoproject.com/wiki/Version1.2Features although I can't for the moment find any discussion.
Daniel Roseman
@Daniel - hope you don't mind, edited in a comment about Django 1.2.
Dominic Rodger
django 1.2 has this. @nbv4
Wahnfrieden
+4  A: 

I'll start.

http://www.djangosnippets.org/snippets/1350/

Smart {% if %} template tag

If you've ever found yourself needing more than a test for True, this tag is for you. It supports equality, greater than, and less than operators.

Simple Example

{% block list-products %}
    {% if products|length > 12 %}
        <!-- Code for pagination -->
    {% endif %}

    <!-- Code for displaying 12 products on the page -->

{% endblock %}
Eric Palakovich Carr
I've also got smartif packaged up as a proper django app: http://github.com/thraxil/django-smartif
thraxil
Ah, handy. Thanks. Also, I wanted to thank you your article "Django Deployment with virtualenv and pip". It's been really helpful:http://thraxil.org/users/anders/posts/2009/06/12/Django-Deployment-with-virtualenv-and-pip/
Eric Palakovich Carr
django 1.2 has this natively
Wahnfrieden
+1  A: 

James Bennet's over-the-top-dynamic get_latest tag

edit as response to jpartogi's comment

class GetItemsNode(Node):
    def __init__(self, model, num, by, varname):
        self.num, self.varname = num, varname
        self.model = get_model(*model.split('.'))
        self.by = by

    def render(self, context):
        if hasattr(self.model, 'publicmgr') and not context['user'].is_authenticated():
            context[self.varname] = self.model.publicmgr.all().order_by(self.by)[:self.num]
        else:
            context[self.varname] = self.model._default_manager.all().order_by(self.by)[:self.num]
        return  ''

<div id="news_portlet" class="portlet">
{% get_sorted_items cms.news 5 by -created_on as items %}
{% include 'snippets/dl.html' %}
</div>
<div id="event_portlet" class="portlet">
{% get_sorted_items cms.event 5 by date as items %}
{% include 'snippets/dl.html' %}
</div>

I call it get_sorted_items, but it is based on James' blog-post

vikingosegundo
That get_latest tag is not really flexible especially when you have many criterias.
jpartogi
with a custom manager you should be able to solve those problems. Of cause get_latest most be adapted. see my edit for an rough example.
vikingosegundo
+1  A: 

In come case {% autopaginate queryset %} (http://code.google.com/p/django-pagination/) is useful. For example:

#views.py
    obj_list = News.objects.filter(status=News.PUBLISHED)
    # do not use len(obj_list) - it's evaluate QuerySet
    obj_count = obj_list.count()


#news_index.html
    {% load pagination_tags %}
    ...
    # do not use {% if obj_list %}
    {% if obj_count %}
        <div class="news">
        <ul>
        {% autopaginate obj_list 10 %}
        {% for item in obj_list %}
            <li><a href="...">{{ item.title }}</a></li>
        {% endfor %}
        </ul>
        </div>
        {% paginate %}
    {% else %}
        Empty list
    {% endif %}

Note, that obj_list must be lazy - read http://docs.djangoproject.com/en/dev/ref/models/querysets/#id1

hardtop