Fixed #10870 -- Added aggreation + generic reverse relation test
This commit is contained in:
parent
b4492a8ca4
commit
3e71368423
|
@ -1,4 +1,6 @@
|
|||
# coding: utf-8
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
|
||||
|
@ -22,6 +24,13 @@ class Publisher(models.Model):
|
|||
return self.name
|
||||
|
||||
|
||||
class TaggedItem(models.Model):
|
||||
tag = models.CharField(max_length=100)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Book(models.Model):
|
||||
isbn = models.CharField(max_length=9)
|
||||
|
@ -33,6 +42,7 @@ class Book(models.Model):
|
|||
contact = models.ForeignKey(Author, related_name='book_contact_set')
|
||||
publisher = models.ForeignKey(Publisher)
|
||||
pubdate = models.DateField()
|
||||
tags = generic.GenericRelation(TaggedItem)
|
||||
|
||||
class Meta:
|
||||
ordering = ('name',)
|
||||
|
@ -63,6 +73,14 @@ class Clues(models.Model):
|
|||
Clue = models.CharField(max_length=150)
|
||||
|
||||
|
||||
class WithManualPK(models.Model):
|
||||
# The generic relations regression test needs two different model
|
||||
# classes with the same PK value, and there are some (external)
|
||||
# DB backends that don't work nicely when assigning integer to AutoField
|
||||
# column (MSSQL at least).
|
||||
id = models.IntegerField(primary_key=True)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class HardbackBook(Book):
|
||||
weight = models.FloatField()
|
||||
|
|
|
@ -6,11 +6,13 @@ from decimal import Decimal
|
|||
from operator import attrgetter
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F, Q
|
||||
from django.test import TestCase, Approximate, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
|
||||
from .models import Author, Book, Publisher, Clues, Entries, HardbackBook
|
||||
from .models import (Author, Book, Publisher, Clues, Entries, HardbackBook,
|
||||
TaggedItem, WithManualPK)
|
||||
|
||||
|
||||
class AggregationTests(TestCase):
|
||||
|
@ -982,3 +984,39 @@ class AggregationTests(TestCase):
|
|||
def test_reverse_join_trimming(self):
|
||||
qs = Author.objects.annotate(Count('book_contact_set__contact'))
|
||||
self.assertIn(' JOIN ', str(qs.query))
|
||||
|
||||
def test_aggregation_with_generic_reverse_relation(self):
|
||||
"""
|
||||
Regression test for #10870: Aggregates with joins ignore extra
|
||||
filters provided by setup_joins
|
||||
|
||||
tests aggregations with generic reverse relations
|
||||
"""
|
||||
b = Book.objects.get(name='Practical Django Projects')
|
||||
TaggedItem.objects.create(object_id=b.id, tag='intermediate',
|
||||
content_type=ContentType.objects.get_for_model(b))
|
||||
TaggedItem.objects.create(object_id=b.id, tag='django',
|
||||
content_type=ContentType.objects.get_for_model(b))
|
||||
# Assign a tag to model with same PK as the book above. If the JOIN
|
||||
# used in aggregation doesn't have content type as part of the
|
||||
# condition the annotation will also count the 'hi mom' tag for b.
|
||||
wmpk = WithManualPK.objects.create(id=b.pk)
|
||||
TaggedItem.objects.create(object_id=wmpk.id, tag='hi mom',
|
||||
content_type=ContentType.objects.get_for_model(wmpk))
|
||||
b = Book.objects.get(name__startswith='Paradigms of Artificial Intelligence')
|
||||
TaggedItem.objects.create(object_id=b.id, tag='intermediate',
|
||||
content_type=ContentType.objects.get_for_model(b))
|
||||
|
||||
self.assertEqual(Book.objects.aggregate(Count('tags')), {'tags__count': 3})
|
||||
results = Book.objects.annotate(Count('tags')).order_by('-tags__count', 'name')
|
||||
self.assertEqual(
|
||||
[(b.name, b.tags__count) for b in results],
|
||||
[
|
||||
('Practical Django Projects', 2),
|
||||
('Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 1),
|
||||
('Artificial Intelligence: A Modern Approach', 0),
|
||||
('Python Web Development with Django', 0),
|
||||
('Sams Teach Yourself Django in 24 Hours', 0),
|
||||
('The Definitive Guide to Django: Web Development Done Right', 0)
|
||||
]
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue