Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.6.x] Fixed #21126 -- QuerySet value conversion failure

A .annotate().select_related() query resulted in misaligned rows vs
columns for compiler.resolve_columns() method.

Report & patch by Michael Manfre.

Backpatch of 83554b0 from master.
  • Loading branch information...
commit d7ae0bc372f8423e7bcf9b5408df46fd5c8dc27d 1 parent 5207928
Anssi Kääriäinen authored September 23, 2013
2  django/db/backends/__init__.py
@@ -1125,7 +1125,7 @@ def convert_values(self, value, field):
1125 1125
         Coerce the value returned by the database backend into a consistent type
1126 1126
         that is compatible with the field type.
1127 1127
         """
1128  
-        if value is None:
  1128
+        if value is None or field is None:
1129 1129
             return value
1130 1130
         internal_type = field.get_internal_type()
1131 1131
         if internal_type == 'FloatField':
12  django/db/models/sql/compiler.py
@@ -709,6 +709,10 @@ def results_iter(self):
709 709
         has_aggregate_select = bool(self.query.aggregate_select)
710 710
         for rows in self.execute_sql(MULTI):
711 711
             for row in rows:
  712
+                if has_aggregate_select:
  713
+                    loaded_fields = self.query.get_loaded_field_names().get(self.query.model, set()) or self.query.select
  714
+                    aggregate_start = len(self.query.extra_select) + len(loaded_fields)
  715
+                    aggregate_end = aggregate_start + len(self.query.aggregate_select)
712 716
                 if resolve_columns:
713 717
                     if fields is None:
714 718
                         # We only set this up here because
@@ -735,12 +739,14 @@ def results_iter(self):
735 739
                             db_table = self.query.get_meta().db_table
736 740
                             fields = [f for f in fields if db_table in only_load and
737 741
                                       f.column in only_load[db_table]]
  742
+                        if has_aggregate_select:
  743
+                            # pad None in to fields for aggregates
  744
+                            fields = fields[:aggregate_start] + [
  745
+                                None for x in range(0, aggregate_end - aggregate_start)
  746
+                            ] + fields[aggregate_start:]
738 747
                     row = self.resolve_columns(row, fields)
739 748
 
740 749
                 if has_aggregate_select:
741  
-                    loaded_fields = self.query.get_loaded_field_names().get(self.query.model, set()) or self.query.select
742  
-                    aggregate_start = len(self.query.extra_select) + len(loaded_fields)
743  
-                    aggregate_end = aggregate_start + len(self.query.aggregate_select)
744 750
                     row = tuple(row[:aggregate_start]) + tuple([
745 751
                         self.query.resolve_aggregate(value, aggregate, self.connection)
746 752
                         for (alias, aggregate), value
11  tests/aggregation_regress/tests.py
@@ -387,6 +387,17 @@ def test_db_col_table(self):
387 387
         qs = Entries.objects.annotate(clue_count=Count('clues__ID'))
388 388
         self.assertQuerysetEqual(qs, [])
389 389
 
  390
+    def test_boolean_conversion(self):
  391
+        # Aggregates mixed up ordering of columns for backend's convert_values
  392
+        # method. Refs #21126.
  393
+        e = Entries.objects.create(Entry='foo')
  394
+        c = Clues.objects.create(EntryID=e, Clue='bar')
  395
+        qs = Clues.objects.select_related('EntryID').annotate(Count('ID'))
  396
+        self.assertQuerysetEqual(
  397
+            qs, [c], lambda x: x)
  398
+        self.assertEqual(qs[0].EntryID, e)
  399
+        self.assertIs(qs[0].EntryID.Exclude, False)
  400
+
390 401
     def test_empty(self):
391 402
         # Regression for #10089: Check handling of empty result sets with
392 403
         # aggregates

0 notes on commit d7ae0bc

Please sign in to comment.
Something went wrong with that request. Please try again.