Ticket #6811: qs_value_expressions.2.diff

File qs_value_expressions.2.diff, 4.8 KB (added by Justin, 17 years ago)

fixed a auto-grouping bug in first patch. added keyword alias support

  • django/db/models/sql/query.py

     
    11701170        """
    11711171        return not (self.low_mark or self.high_mark)
    11721172
    1173     def add_fields(self, field_names, allow_m2m=True):
     1173    def add_fields(self, fields, allow_m2m=True):
    11741174        """
    11751175        Adds the given (model) fields to the select set. The field names are
    11761176        added in the order specified.
    11771177        """
    11781178        alias = self.get_initial_alias()
    11791179        opts = self.get_meta()
     1180        auto_group = False
     1181        group_fields = []
    11801182        try:
    1181             for name in field_names:
    1182                 u1, target, u2, joins = self.setup_joins(name.split(LOOKUP_SEP),
    1183                         opts, alias, False, allow_m2m, True)
    1184                 self.select.append((joins[-1][-1], target.column))
     1183            for f in fields:
     1184                if isinstance(f, str):
     1185                    u1, target, u2, joins = self.setup_joins(f.split(LOOKUP_SEP),
     1186                            opts, alias, False, allow_m2m, True)
     1187                    self.select.append((joins[-1][-1], target.column))
     1188                    group_fields.append((joins[-1][-1], target.column))
     1189                else:
     1190                    if hasattr(f, 'get_cols'):
     1191                        table_map = {}
     1192                        column_map = {}
     1193                        for col in f.get_cols():
     1194                            u1, target, u2, joins = self.setup_joins(col.split(LOOKUP_SEP),
     1195                                    opts, alias, False, allow_m2m, True)
     1196                            table_map[''] = joins[-1][-1]
     1197                            column_map[col] = target.column
     1198                        f.relabel_aliases(table_map, column_map)
     1199                    if hasattr(f, 'do_group'):
     1200                        auto_group = f.do_group()
     1201                    self.select.append(f)
     1202            if auto_group:
     1203                self.group_by.extend(group_fields)
    11851204        except JoinError:
    1186             raise FieldError("Invalid field name: '%s'" % name)
     1205            raise FieldError("Invalid field name: '%s'" % f)
    11871206
    11881207    def add_ordering(self, *ordering):
    11891208        """
  • django/db/models/query.py

     
    284284    # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
    285285    ##################################################
    286286
    287     def values(self, *fields):
    288         return self._clone(klass=ValuesQuerySet, setup=True, _fields=fields)
    289 
     287    def values(self, *fields, **aliased_fields):
     288        return self._clone(klass=ValuesQuerySet, setup=True, _fields=fields, _aliased_fields=aliased_fields)
     289   
    290290    def valueslist(self, *fields, **kwargs):
    291291        flat = kwargs.pop('flat', False)
    292292        if kwargs:
     
    489489        Called by the _clone() method after initialising the rest of the
    490490        instance.
    491491        """
     492        # field_names contains strings
     493        # fields contains strings or expression objects
     494        field_names = []
     495        fields = []
    492496        if self._fields:
    493497            if not self.query.extra_select:
    494                 field_names = list(self._fields)
     498                field_names = list(f.output_alias() if hasattr(f,'output_alias') else f for f in self._fields)
     499                fields = list(self._fields)
    495500            else:
    496                 field_names = []
    497501                names = set(self.model._meta.get_all_field_names())
    498502                for f in self._fields:
    499503                    if f in names:
    500504                        field_names.append(f)
     505                        fields.append(f)
     506                    elif hasattr(f, 'output_alias'):
     507                        field_names.append(f.output_alias())
     508                        fields.append(f)
    501509                    elif not self.query.extra_select.has_key(f):
    502510                        raise FieldDoesNotExist('%s has no field named %r'
    503511                                % (self.model._meta.object_name, f))
    504         else:
     512        if self._aliased_fields:
     513            items = self._aliased_fields.items()
     514            field_names += [i[0] for i in items]
     515            fields += [i[1] for i in items]
     516        if not (self._aliased_fields or self._fields):
    505517            # Default to all fields.
    506             field_names = [f.attname for f in self.model._meta.fields]
    507 
    508         self.query.add_fields(field_names, False)
     518            fields =  [f.attname for f in self.model._meta.fields]
     519            field_names = fields[:]
     520               
     521        self.query.add_fields(fields)
    509522        self.query.default_cols = False
    510523        self.field_names = field_names
    511524
Back to Top