annotate() and aggregate() for generically-related data.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs Add history and bump version. Jan 22, 2016
generic_aggregation Remove unused function. Jan 22, 2016
generic_aggregation_tests
.coveragerc Add tox and coverage integration Apr 13, 2015
.gitignore
AUTHORS
History.md Add history and bump version. Jan 22, 2016
LICENSE Initial commit May 31, 2010
MANIFEST.in Adding manifest Aug 7, 2010
README.rst
runtests.py Move test app outside of package for Django 1.9. Jan 22, 2016
settings_migrations.py Add comment. Jan 22, 2016
setup.py
tox.ini Update test environments to recent Django versions. Jan 21, 2016

README.rst

django-generic-aggregation

annotate() and aggregate() for generically-related data. also a handy function for filtering GFK-model querysets.

Use django's GenericRelation where possible, as this can make the queries generated more efficient by using a JOIN rather than a subquery.

installation

# install from pypi
pip install django-generic-aggregation

# or install via git
pip install -e git+git://github.com/coleifer/django-generic-aggregation.git#egg=generic_aggregation

examples

The examples below assume the following simple models:

class Rating(models.Model):
    rating = models.IntegerField()
    object_id = models.IntegerField()
    content_type = models.ForeignKey(ContentType)
    content_object = GenericForeignKey(ct_field='content_type', fk_field='object_id')

class Food(models.Model):
    name = models.CharField(max_length=50)
    ratings = generic.GenericRelation(Rating) # reverse generic relation

You want to figure out which items are highest rated (generic_annotate)

from django.db.models import Avg

food_qs = Food.objects.filter(name__startswith='a')
generic_annotate(food_qs, Rating, Avg('ratings__rating'))

# you can mix and match queryset / model
generic_annotate(food_qs, Rating.objects.all(), Avg('ratings__rating'))

You want the average rating for all foods that start with 'a' (generic_aggregate)

food_qs = Food.objects.filter(name__startswith='a')
generic_aggregate(food_qs, Rating, Avg('ratings__rating'))

You want to only display ratings for foods that start with 'a' (generic_filter)

food_qs = Food.objects.filter(name__startswith='a')
generic_filter(Rating.objects.all(), food_qs)

documentation

https://django-generic-aggregation.readthedocs.io/