diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index f4bf8b2..76d8496 100644
a
|
b
|
class BaseQuery(object):
|
1431 | 1431 | # - this is an annotation over a model field |
1432 | 1432 | # then we need to explore the joins that are required. |
1433 | 1433 | |
1434 | | field, source, opts, join_list, last, _ = self.setup_joins( |
| 1434 | field, source, opts, join_list, last, extra = self.setup_joins( |
1435 | 1435 | field_list, opts, self.get_initial_alias(), False) |
1436 | 1436 | |
1437 | 1437 | # Process the join chain to see if it can be trimmed |
… |
… |
class BaseQuery(object):
|
1444 | 1444 | self.promote_alias(column_alias, unconditional=True) |
1445 | 1445 | |
1446 | 1446 | col = (join_list[-1], col) |
| 1447 | for filter in extra: |
| 1448 | self.add_filter(filter, can_reuse=set(join_list), |
| 1449 | process_extras=False) |
1447 | 1450 | else: |
1448 | 1451 | # The simplest cases. No joins required - |
1449 | 1452 | # just reference the provided column alias. |
diff --git a/tests/regressiontests/aggregation_regress/models.py b/tests/regressiontests/aggregation_regress/models.py
index d1f1451..a8b09a8 100644
a
|
b
|
import pickle
|
3 | 3 | |
4 | 4 | from django.db import models |
5 | 5 | from django.conf import settings |
| 6 | from django.contrib.contenttypes import generic |
| 7 | from django.contrib.contenttypes.models import ContentType |
6 | 8 | |
7 | 9 | try: |
8 | 10 | sorted |
… |
… |
class Book(models.Model):
|
34 | 36 | contact = models.ForeignKey(Author, related_name='book_contact_set') |
35 | 37 | publisher = models.ForeignKey(Publisher) |
36 | 38 | pubdate = models.DateField() |
| 39 | tags = generic.GenericRelation('TaggedItem') |
37 | 40 | |
38 | 41 | class Meta: |
39 | 42 | ordering = ('name',) |
… |
… |
class HardbackBook(Book):
|
66 | 69 | def __unicode__(self): |
67 | 70 | return "%s (hardback): %s" % (self.name, self.weight) |
68 | 71 | |
| 72 | class TaggedItem(models.Model): |
| 73 | tag = models.CharField(max_length=100) |
| 74 | content_type = models.ForeignKey(ContentType, related_name="aggregation_tagged_item_set") |
| 75 | object_id = models.PositiveIntegerField() |
| 76 | content_object = generic.GenericForeignKey('content_type', 'object_id') |
| 77 | |
| 78 | def __unicode__(self): |
| 79 | return "%s tagged with %s" % (self.content_object, self.tag) |
| 80 | |
| 81 | |
69 | 82 | __test__ = {'API_TESTS': """ |
70 | 83 | >>> from django.core import management |
71 | 84 | >>> from django.db.models import get_app, F |
… |
… |
__test__ = {'API_TESTS': """
|
145 | 158 | >>> Book.objects.all().aggregate(num_authors=Count('foo')) |
146 | 159 | Traceback (most recent call last): |
147 | 160 | ... |
148 | | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store |
| 161 | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags |
149 | 162 | |
150 | 163 | >>> Book.objects.all().annotate(num_authors=Count('foo')) |
151 | 164 | Traceback (most recent call last): |
152 | 165 | ... |
153 | | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store |
| 166 | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags |
154 | 167 | |
155 | 168 | >>> Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo')) |
156 | 169 | Traceback (most recent call last): |
157 | 170 | ... |
158 | | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, num_authors |
| 171 | FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags, num_authors |
159 | 172 | |
160 | 173 | # Old-style count aggregations can be mixed with new-style |
161 | 174 | >>> Book.objects.annotate(num_authors=Count('authors')).count() |
… |
… |
True
|
317 | 330 | Traceback (most recent call last): |
318 | 331 | ... |
319 | 332 | FieldError: Cannot compute Avg('mean_age'): 'mean_age' is an aggregate |
320 | | |
| 333 | >>> b = Book.objects.get(name='Practical Django Projects') |
| 334 | >>> _ = TaggedItem.objects.create(object_id=b.id, content_type=ContentType.objects.get_for_model(b), tag='intermediate') |
| 335 | >>> _ = TaggedItem.objects.create(object_id=b.id, content_type=ContentType.objects.get_for_model(b), tag='django') |
| 336 | >>> b = Book.objects.get(name__startswith='Paradigms of Artificial Intelligence') |
| 337 | >>> _ = TaggedItem.objects.create(object_id=b.id, content_type=ContentType.objects.get_for_model(b), tag='intermediate') |
| 338 | |
| 339 | >>> s = Store.objects.get(name__startswith='Amazon') |
| 340 | >>> _ = TaggedItem.objects.create(object_id=s.id, content_type=ContentType.objects.get_for_model(s), tag='online') |
| 341 | >>> Book.objects.aggregate(Count('tags')) |
| 342 | {'tags__count': 3} |
| 343 | |
| 344 | >>> [(b.name, b.tags__count) for b in Book.objects.annotate(Count('tags')).order_by('-tags__count')[:2]] |
| 345 | [(u'Practical Django Projects', 2), (u'Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 1)] |
| 346 | >>> list(Book.objects.annotate(Count('tags')).order_by('name')) == list(Book.objects.order_by('name')) |
| 347 | True |
| 348 | >>> print Book.objects.annotate(Count('tags')).order_by('name').query |
321 | 349 | """ |
322 | 350 | } |
323 | 351 | |