diff options
author | Simon Charette <charette.s@gmail.com> | 2017-04-29 14:53:43 -0400 |
---|---|---|
committer | Simon Charette <charette.s@gmail.com> | 2017-05-11 20:00:57 -0400 |
commit | daf2bd3efe53cbfc1c9fd00222b8315708023792 (patch) | |
tree | 8a511bc9124f8eb7bf7739b54ce52f5d071aef9b /tests/aggregation_regress | |
parent | bdf192c59357a0d8117f6f34c94fb32a51e7a774 (diff) | |
download | django-daf2bd3efe53cbfc1c9fd00222b8315708023792.tar.gz |
Fixed #28107 -- Disabled grouping of selected primary keys for unmanaged models.
The grouping caused an issue with database views as PostgreSQL's query planer
isn't smart enough to introspect primary keys through views. Django doesn't
support database views but documents that unmanaged models should be used to
query them.
Thanks powderflask for the detailed report and investigation.
Diffstat (limited to 'tests/aggregation_regress')
-rw-r--r-- | tests/aggregation_regress/tests.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index bc501fc94e..7dc9a95688 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -2,6 +2,7 @@ import datetime import pickle from decimal import Decimal from operator import attrgetter +from unittest import mock from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldError @@ -1262,6 +1263,42 @@ class AggregationTests(TestCase): ] ) + @skipUnlessDBFeature('allows_group_by_selected_pks') + def test_aggregate_ummanaged_model_columns(self): + """ + Unmanaged models are sometimes used to represent database views which + may not allow grouping by selected primary key. + """ + def assertQuerysetResults(queryset): + self.assertEqual( + [(b.name, b.num_authors) for b in queryset.order_by('name')], + [ + ('Artificial Intelligence: A Modern Approach', 2), + ('Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp', 1), + ('Practical Django Projects', 1), + ('Python Web Development with Django', 3), + ('Sams Teach Yourself Django in 24 Hours', 1), + ('The Definitive Guide to Django: Web Development Done Right', 2), + ] + ) + queryset = Book.objects.select_related('contact').annotate(num_authors=Count('authors')) + # Unmanaged origin model. + with mock.patch.object(Book._meta, 'managed', False): + _, _, grouping = queryset.query.get_compiler(using='default').pre_sql_setup() + self.assertEqual(len(grouping), len(Book._meta.fields) + 1) + for index, field in enumerate(Book._meta.fields): + self.assertIn(field.name, grouping[index][0]) + self.assertIn(Author._meta.pk.name, grouping[-1][0]) + assertQuerysetResults(queryset) + # Unmanaged related model. + with mock.patch.object(Author._meta, 'managed', False): + _, _, grouping = queryset.query.get_compiler(using='default').pre_sql_setup() + self.assertEqual(len(grouping), len(Author._meta.fields) + 1) + self.assertIn(Book._meta.pk.name, grouping[0][0]) + for index, field in enumerate(Author._meta.fields): + self.assertIn(field.name, grouping[index + 1][0]) + assertQuerysetResults(queryset) + def test_reverse_join_trimming(self): qs = Author.objects.annotate(Count('book_contact_set__contact')) self.assertIn(' JOIN ', str(qs.query)) |