Ticket #10870: aggregation-generic.3.diff

File aggregation-generic.3.diff, 5.3 KB (added by Alex, 6 years ago)

Added a test to show it doesn't work with annotate, for some reason it only returns books that have been tagged, which doesn't match the behavior of any other annotation, it's an annotation not a filter, I assume this is the result of using the wrong join type

  • django/db/models/sql/query.py

    diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
    index f4bf8b2..7df3baf 100644
    a b class BaseQuery(object): 
    14311431            #   - this is an annotation over a model field
    14321432            # then we need to explore the joins that are required.
    14331433
    1434             field, source, opts, join_list, last, _ = self.setup_joins(
     1434            field, source, opts, join_list, last, extra = self.setup_joins(
    14351435                field_list, opts, self.get_initial_alias(), False)
     1436            # add any extra filters that are needed
    14361437
    14371438            # Process the join chain to see if it can be trimmed
    14381439            col, _, join_list = self.trim_joins(source, join_list, last, False)
    class BaseQuery(object): 
    14441445                self.promote_alias(column_alias, unconditional=True)
    14451446
    14461447            col = (join_list[-1], col)
     1448            if extra:
     1449                for filter in extra:
     1450                    self.add_filter(filter, can_reuse=set(join_list),
     1451                        process_extras=False)
    14471452        else:
    14481453            # The simplest cases. No joins required -
    14491454            # just reference the provided column alias.
  • tests/regressiontests/aggregation_regress/models.py

    diff --git a/tests/regressiontests/aggregation_regress/models.py b/tests/regressiontests/aggregation_regress/models.py
    index d1f1451..1974615 100644
    a b import pickle 
    33
    44from django.db import models
    55from django.conf import settings
     6from django.contrib.contenttypes import generic
     7from django.contrib.contenttypes.models import ContentType
    68
    79try:
    810    sorted
    class Book(models.Model): 
    3436    contact = models.ForeignKey(Author, related_name='book_contact_set')
    3537    publisher = models.ForeignKey(Publisher)
    3638    pubdate = models.DateField()
     39    tags = generic.GenericRelation('TaggedItem')
    3740
    3841    class Meta:
    3942        ordering = ('name',)
    class HardbackBook(Book): 
    6669    def __unicode__(self):
    6770        return "%s (hardback): %s" % (self.name, self.weight)
    6871
     72class 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
    6982__test__ = {'API_TESTS': """
    7083>>> from django.core import management
    7184>>> from django.db.models import get_app, F
    __test__ = {'API_TESTS': """ 
    145158>>> Book.objects.all().aggregate(num_authors=Count('foo'))
    146159Traceback (most recent call last):
    147160...
    148 FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store
     161FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags
    149162
    150163>>> Book.objects.all().annotate(num_authors=Count('foo'))
    151164Traceback (most recent call last):
    152165...
    153 FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store
     166FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags
    154167
    155168>>> Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo'))
    156169Traceback (most recent call last):
    157170...
    158 FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, num_authors
     171FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, contact, hardbackbook, id, isbn, name, pages, price, pubdate, publisher, rating, store, tags, num_authors
    159172
    160173# Old-style count aggregations can be mixed with new-style
    161174>>> Book.objects.annotate(num_authors=Count('authors')).count()
    True 
    317330Traceback (most recent call last):
    318331...
    319332FieldError: 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'))
     347True
    321348"""
    322349}
    323350
Back to Top