Django

Code

Changeset 7240

Show
Ignore:
Timestamp:
03/14/08 06:45:52 (8 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Fixed default (no fields) case of select_related() to work with model inheritance. Refs #6761.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/query.py

    r7235 r7240  
    599599def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0, 
    600600        requested=None): 
    601     """Helper function that recursively returns an object with cache filled""" 
    602  
     601    """ 
     602    Helper function that recursively returns an object with the specified 
     603    related attributes already populated. 
     604    """ 
    603605    if max_depth and requested is None and cur_depth > max_depth: 
    604606        # We've recursed deeply enough; stop now. 
     
    609611    obj = klass(*row[index_start:index_end]) 
    610612    for f in klass._meta.fields: 
    611         if f.rel and ((not restricted and not f.null) or 
    612                 (restricted and f.name in requested)): 
    613             if restricted: 
    614                 next = requested[f.name] 
    615             else: 
    616                 next = None 
    617             cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, 
    618                     cur_depth+1, next) 
    619             if cached_row: 
    620                 rel_obj, index_end = cached_row 
    621                 setattr(obj, f.get_cache_name(), rel_obj) 
     613        if (not f.rel or (not restricted and f.null) or 
     614                (restricted and f.name not in requested) or f.rel.parent_link): 
     615            continue 
     616        if restricted: 
     617            next = requested[f.name] 
     618        else: 
     619            next = None 
     620        cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, 
     621                cur_depth+1, next) 
     622        if cached_row: 
     623            rel_obj, index_end = cached_row 
     624            setattr(obj, f.get_cache_name(), rel_obj) 
    622625    return obj, index_end 
    623626 
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r7235 r7240  
    4545        self.alias_map = {}     # Maps alias to table name 
    4646        self.table_map = {}     # Maps table names to list of aliases. 
    47         self.rev_join_map = {}  # Reverse of join_map. 
     47        self.rev_join_map = {}  # Reverse of join_map. (FIXME: Update comment) 
    4848        self.quote_cache = {} 
    4949        self.default_cols = True 
     
    6464        self.select_related = False 
    6565 
    66         # Arbitrary maximum limit for select_related to prevent infinite 
     66        # Arbitrary maximum limit for select_related. Prevents infinite 
    6767        # recursion. Can be changed by the depth parameter to select_related(). 
    6868        self.max_depth = 5 
     
    362362                        aliases.append(col.alias) 
    363363        elif self.default_cols: 
    364             table_alias = self.tables[0] 
    365             root_pk = self.model._meta.pk.column 
    366             seen = {None: table_alias} 
    367             for field, model in self.model._meta.get_fields_with_model(): 
    368                 if model not in seen: 
    369                     seen[model] = self.join((table_alias, model._meta.db_table, 
    370                             root_pk, model._meta.pk.column)) 
    371                 result.append('%s.%s' % (qn(seen[model]), qn(field.column))) 
     364            #table_alias = self.tables[0] 
     365            #root_pk = self.model._meta.pk.column 
     366            #seen = {None: table_alias} 
     367            #for field, model in self.model._meta.get_fields_with_model(): 
     368            #    if model not in seen: 
     369            #        seen[model] = self.join((table_alias, model._meta.db_table, 
     370            #                root_pk, model._meta.pk.column)) 
     371            #    result.append('%s.%s' % (qn(seen[model]), qn(field.column))) 
     372            result = self.get_default_columns(lambda x, y: "%s.%s" % (qn(x), qn(y))) 
    372373            aliases = result[:] 
    373374 
     
    377378 
    378379        self._select_aliases = dict.fromkeys(aliases) 
     380        return result 
     381 
     382    def get_default_columns(self, combine_func=None): 
     383        """ 
     384        Computes the default columns for selecting every field in the base 
     385        model. Returns a list of default (alias, column) pairs suitable for 
     386        direct inclusion as the select columns. The 'combine_func' can be 
     387        passed in to change the returned data set to a list of some other 
     388        structure. 
     389        """ 
     390        # Note: We allow 'combine_func' here because this method is called a 
     391        # lot. The extra overhead from returning a list and then transforming 
     392        # it in get_columns() hurt performance in a measurable way. 
     393        result = [] 
     394        table_alias = self.tables[0] 
     395        root_pk = self.model._meta.pk.column 
     396        seen = {None: table_alias} 
     397        for field, model in self.model._meta.get_fields_with_model(): 
     398            if model not in seen: 
     399                seen[model] = self.join((table_alias, model._meta.db_table, 
     400                        root_pk, model._meta.pk.column)) 
     401            if combine_func: 
     402                result.append(combine_func(seen[model], field.column)) 
     403            else: 
     404                result.append((seen[model], field.column)) 
    379405        return result 
    380406 
     
    745771            opts = self.get_meta() 
    746772            root_alias = self.tables[0] 
    747             self.select.extend([(root_alias, f.column) for f in opts.fields]
     773            self.select.extend(self.get_default_columns()
    748774        if not used: 
    749775            used = [] 
     
    760786        for f in opts.fields: 
    761787            if (not f.rel or (restricted and f.name not in requested) or 
    762                     (not restricted and f.null)): 
     788                    (not restricted and f.null) or f.rel.parent_link): 
    763789                continue 
    764790            table = f.rel.to._meta.db_table