Fixed #14754 -- corrected using an aggregate in an F expressions when that queryset is later used in a subquery. Thanks to master for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14681 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2010-11-22 18:00:01 +00:00
parent 2596cf1652
commit 07ba3220ba
3 changed files with 23 additions and 10 deletions

View File

@ -19,6 +19,9 @@ class SQLEvaluator(object):
def relabel_aliases(self, change_map): def relabel_aliases(self, change_map):
for node, col in self.cols.items(): for node, col in self.cols.items():
if hasattr(col, "relabel_aliases"):
col.relabel_aliases(change_map)
else:
self.cols[node] = (change_map.get(col[0], col[0]), col[1]) self.cols[node] = (change_map.get(col[0], col[0]), col[1])
##################################################### #####################################################

View File

@ -1,8 +1,5 @@
# coding: utf-8 # coding: utf-8
import pickle from django.db import models
from django.db import connection, models, DEFAULT_DB_ALIAS
from django.conf import settings
class Author(models.Model): class Author(models.Model):
@ -49,7 +46,6 @@ class Store(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class Entries(models.Model): class Entries(models.Model):
EntryID = models.AutoField(primary_key=True, db_column='Entry ID') EntryID = models.AutoField(primary_key=True, db_column='Entry ID')
Entry = models.CharField(unique=True, max_length=50) Entry = models.CharField(unique=True, max_length=50)

View File

@ -1,13 +1,13 @@
import datetime import datetime
import pickle
from decimal import Decimal from decimal import Decimal
from operator import attrgetter
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.conf import settings
from django.test import TestCase, Approximate, skipUnlessDBFeature from django.test import TestCase, Approximate, skipUnlessDBFeature
from django.db import DEFAULT_DB_ALIAS
from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F from django.db.models import Count, Max, Avg, Sum, StdDev, Variance, F
from regressiontests.aggregation_regress.models import * from models import Author, Book, Publisher, Clues, Entries, HardbackBook
class AggregationTests(TestCase): class AggregationTests(TestCase):
@ -482,7 +482,7 @@ class AggregationTests(TestCase):
# Regression for #10197 -- Queries with aggregates can be pickled. # Regression for #10197 -- Queries with aggregates can be pickled.
# First check that pickling is possible at all. No crash = success # First check that pickling is possible at all. No crash = success
qs = Book.objects.annotate(num_authors=Count('authors')) qs = Book.objects.annotate(num_authors=Count('authors'))
out = pickle.dumps(qs) pickle.dumps(qs)
# Then check that the round trip works. # Then check that the round trip works.
query = qs.query.get_compiler(qs.db).as_sql()[0] query = qs.query.get_compiler(qs.db).as_sql()[0]
@ -640,6 +640,20 @@ class AggregationTests(TestCase):
Author.objects.count() Author.objects.count()
) )
def test_f_expression_annotation(self):
# Books with less than 200 pages per author.
qs = Book.objects.values("name").annotate(
n_authors=Count("authors")
).filter(
pages__lt=F("n_authors") * 200
).values_list("pk")
self.assertQuerysetEqual(
Book.objects.filter(pk__in=qs), [
"Python Web Development with Django"
],
attrgetter("name")
)
@skipUnlessDBFeature('supports_stddev') @skipUnlessDBFeature('supports_stddev')
def test_stddev(self): def test_stddev(self):
self.assertEqual( self.assertEqual(