Implementing CNN Style Votes In Django, Episode II
Now that we have voting implemented, see Implementing CNN Style Votes In Django, Episode I, it would be usefull to add a mechanism for displaying the voted on items just as easily. This functionality again exists on my www.joosthot.com site, just look at the top right where i use this code to select the #1 item in each category.
Requirements
- Listing may be implemented on any page.
- Must have ability to list different item types on the same page.
- Display any template defined quantity of items sorted by vote.
- Easily extend the voting list to any table in the model.
Design
First define the template tag that will query the database and retrieve items based on votes. This code is based on the work of James Bennett on his blog. This is the same principle as we used in Episode I, the code is generic using get_model(…). The only piece of informnation that needs to be modified is the import to ensure the correct models are accessible.
from django import template
from django.template import Library, Node
from django.db.models import get_model
from grab.joosthot.models import Gallery
from grab.joosthot.models import YouTube
from grab.joosthot.models import MySpace
from grab.joosthot.models import Quote
register = template.Library()
class BestContentNode(Node):
def __init__(self, model, num, varname):
self.num, self.varname = num, varname
self.model = get_model(*model.split('.'))
def render(self, context):
context[self.varname] = self.model.objects.all()[:self.num]
return ''
def get_best(parser, token):
bits = token.contents.split()
if len(bits) != 5:
raise TemplateSyntaxError, "get_best tag takes exactly four arguments"
if bits[3] != 'as':
raise TemplateSyntaxError, "third argument to get_best tag must be 'as'"
return BestContentNode(bits[1], bits[2], bits[4])
register.tag('get_best', get_best)
Now that youve got the template tag defined you need to call it from each template as desired. The interface has 3 components.
- model name – the name of the model to query, must be one of the imports in the template tag defined above.
- quantity – number of items to return, note that model definition indicates sort by vote descending. Again see Episode I.
- template variable – the variable name under whish to store the results. This allows muliple fetches of different models within the same template.
With the three components above the intarface looks like:
{% get_best joosthot.MySpace 5 as best_profile %}
{% for p in best_profile %}
{{ p.name }}
{{ p.votes }} Votes
{% endfor %}
{% get_best joosthot.Gallery 7 as best_gallery %}
{% for g in best_gallery %}
{{ g.title }}
{{ g.votes }} Votes
{% endfor %}
Gotchas
Make sure you place the python code in a directory called templatetags, otherwise you will get an error indicating that get_best is not found. Django is strict that way (at least by default) so save yourself some time and create a templatetags directory under your project folder. You do NOT need any special settings.py changes.
Conclusion
Now you can quickly and easily display ranked voted items in any template anywhere on your pages. This tag is great for top ten in each category pages or even simple top one summary lists for all categories.
More from Aware Labs
- Implementing CNN style votes in Django, Episode I
- Using Django Models In Batch Jobs
- Custom Actions In Django Admin Object Editor
- Django Generic Relations Made Easier
- Full Source To Instant RSS Portals Using Django
Aware Labs Recommends
- Popularizing Django — Or Reusable apps considered harmful. (USwaretech)
- Django’s tipping point (Antonio Cangiano)
- An Interview with Jacob Kaplan-Moss – Creator of Django (USwaretech)

![Recommend [AwareLabs]](http://s3.amazonaws.com/arkayne-media/img/badge/logo-recommend-badge-medium.png)