[1.2.X] 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. Backport of [14681].

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14682 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2010-11-22 18:02:33 +00:00
parent 56b9e0c45f
commit c2de746ea5
3 changed files with 25 additions and 10 deletions

View File

@ -19,7 +19,10 @@ 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():
self.cols[node] = (change_map.get(col[0], col[0]), col[1]) if hasattr(col, "relabel_aliases"):
col.relabel_aliases(change_map)
else:
self.cols[node] = (change_map.get(col[0], col[0]), col[1])
##################################################### #####################################################
# Vistor methods for initial expression preparation # # Vistor methods for initial expression preparation #

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,15 @@
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.conf import settings from django.conf import settings
from django.test import TestCase, Approximate from django.core.exceptions import FieldError
from django.db import DEFAULT_DB_ALIAS 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 django.test import TestCase, Approximate
from regressiontests.aggregation_regress.models import * from models import Author, Book, Publisher, Clues, Entries, HardbackBook
def run_stddev_tests(): def run_stddev_tests():
@ -501,7 +503,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]
@ -659,6 +661,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")
)
if run_stddev_tests(): if run_stddev_tests():
def test_stddev(self): def test_stddev(self):
self.assertEqual( self.assertEqual(