Created
November 12, 2009 20:44
-
-
Save codiez/233262 to your computer and use it in GitHub Desktop.
Django - Generic Custom Model Manager for summarizing data by any field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
This Snippet, lets you create a generic custom model manager to summarize data on a table by any field. | |
Benefits: | |
- You wont be repeating yourself! | |
- A single url & template can be used to summarize by any field in your model | |
Example Usage: Book.counts.by(field, year, month, day) i.e Book.counts.by(category, 2009, 9, 24) | |
Notes: | |
- day is optional | |
- My current use case only requires summaries by month/day, this snippet could easily be modified to make both month and year optional using **kwargs | |
Instructions: | |
1. Create your custom model manager & assign it to your model (models.py) | |
2. Create your view (views.py) | |
3. Add urls (urls.py) | |
4. Create a new template tag and register it (get.py) | |
5. Customize your template | |
''' | |
from django.db import models | |
from django.db.models import Count | |
# Snippet for your models.py | |
class CountsManager(models.Manager): | |
def by(self, field, year, month, *args): | |
year = year | |
month = month | |
field = field | |
if args: | |
day = args[0] | |
return self.filter(pub_date_time__year=year).filter(pub_date_time__month=month).filter(pub_date_time__day=day).values(field).annotate(Count(field)) | |
else: | |
return self.filter(pub_date_time__year=year).filter(pub_date_time__month=month).values(field).annotate(Count(field)) | |
# Add the custom manager to your model | |
class Book(models.Model): | |
pub_date_time = models.DateTimeField(blank=True, null=True) | |
author = models.CharField(max_length=50,blank=True, null=True) | |
publisher = models.CharField(max_length=50,blank=True, null=True) | |
category = models.CharField(max_length=50,blank=True, null=True) | |
objects = models.Manager() | |
counts = CountsManager() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.views.generic.list_detail import object_list | |
from myproject.app.models import Book | |
# Snippet for your views.py | |
def by(request, field, year , month, **kwargs): | |
field = field | |
field_count = field + "__count" | |
context = {'year': year, 'month': month, 'field': field, 'field_count': field_count} | |
if kwargs: | |
day = kwargs['day'] | |
query = Book.counts.by(field, year, month, day) | |
context['day'] = day | |
else: | |
query = Book.counts.by(field, year, month) | |
template = 'type.html' | |
return object_list(request, | |
queryset=query, | |
template_name = template, | |
extra_context = context | |
) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf.urls.defaults import * | |
# Snippet for your urls.py | |
urlpatterns = patterns('myapp.views', | |
url('^(?P<field>[\w-]+)/(?P<year>\d{4})/(?P<month>\d+)/$','by', name='count_link_month'), | |
url('^(?P<field>[\w-]+)/(?P<year>\d{4})/(?P<month>\d+)/(?P<day>\d+)/$','by', name='chart_link_day'), | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.template import Library | |
register = Library() | |
# Add the following filter in your templatetags dir - Source: http://www.djangosnippets.org/snippets/1412/ | |
@register.filter | |
def get( dict, key, default = '' ): | |
""" | |
Usage: | |
view: | |
some_dict = {'keyA':'valueA','keyB':{'subKeyA':'subValueA','subKeyB':'subKeyB'},'keyC':'valueC'} | |
keys = ['keyA','keyC'] | |
template: | |
{{ some_dict|get:"keyA" }} | |
{{ some_dict|get:"keyB"|get:"subKeyA" }} | |
{% for key in keys %}{{ some_dict|get:key }}{% endfor %} | |
""" | |
try: | |
return dict.get(key,default) | |
except: | |
return default + 'Except Clause' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<-- Make your template generic by using the two variables (field & field__count) passed in the context variable customize the code below for your template template --> | |
{% for object in object_list %} | |
<h1>{{ object|get:field }} : {{ object|get:field_count }}</h1> | |
{% endfor %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment