Ticket #11890: 11980_defer_plus_annotate_fix.diff

File 11980_defer_plus_annotate_fix.diff, 4.3 KB (added by ruosteinen, 15 years ago)
  • django/db/models/sql/compiler.py

     
    165165                if isinstance(col, (list, tuple)):
    166166                    alias, column = col
    167167                    table = self.query.alias_map[alias][TABLE_NAME]
    168                     if table in only_load and col not in only_load[table]:
     168                    if table in only_load and column not in only_load[table]:
    169169                        continue
    170170                    r = '%s.%s' % (qn(alias), qn(column))
    171171                    if with_aliases:
  • django/db/models/query.py

     
    228228            fields = self.model._meta.fields
    229229            pk_idx = self.model._meta.pk_index()
    230230
    231         index_start = len(extra_select)
    232         aggregate_start = index_start + len(self.model._meta.fields)
    233 
    234231        load_fields = []
    235232        # If only/defer clauses have been specified,
    236233        # build the list of fields that are to be loaded.
     
    249246                    # Model wasn't explicitly listed in the only_load table
    250247                    # Therefore, we need to load all fields from this model
    251248                    load_fields.append(field.name)
     249       
     250        index_start = len(extra_select)
     251        # Compute the aggregate value index in result rows
     252        if only_load and self.model in only_load:
     253            # Only the ones not deferred
     254            aggregate_start = index_start + len(only_load[self.model])
     255        else:
     256            # All fields
     257            aggregate_start = index_start + len(self.model._meta.fields)
    252258
    253259        skip = None
    254260        if load_fields and not fill_cache:
     
    264270            model_cls = deferred_class_factory(self.model, skip)
    265271
    266272        compiler = self.query.get_compiler(using=self.db)
     273       
    267274        for row in compiler.results_iter():
    268275            if fill_cache:
    269276                obj, _ = get_cached_row(self.model, row,
  • tests/regressiontests/defer_regress/models.py

     
    144144>>> sorted(get_models(models.get_app('defer_regress'), include_deferred=True), key=lambda obj: obj._meta.object_name)
    145145[<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_text'>, <class 'regressiontests.defer_regress.models.Item_Deferred_other_value_text_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_text_value'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_name_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_second_child_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_value'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_item_id'>, <class 'regressiontests.defer_regress.models.ResolveThis'>, <class 'regressiontests.defer_regress.models.ResolveThis_Deferred_num'>]
    146146
     147# Regression for #11890
     148>>> from django.db.models import Count, Avg
     149>>> Item.objects.all().delete()
     150>>> RelatedItem.objects.all().delete()
     151>>> i = Item.objects.create(name='Bug #11890', value=1)
     152>>> RelatedItem.objects.create(item=i)
     153<RelatedItem: RelatedItem object>
     154>>> RelatedItem.objects.create(item=i)
     155<RelatedItem: RelatedItem object>
     156>>> counted = Item.objects.only('name').annotate(Count('relateditem'))
     157>>> counted.count()
     1581
     159>>> counted[0].relateditem__count
     1602
     161
     162# Adding up some spice since result row index offset is affected by extra selections
     163>>> counted = Item.objects.extra(select={'past': 'now()'}).annotate(rel_count=Count('relateditem'), avg_id=Avg('id')).extra(select={'sometime': 'now()'})
     164>>> counted.count()
     1651
     166>>> counted[0].rel_count
     1672
    147168"""
    148169}
    149170
Back to Top