Ticket #14700: patch.diff

File patch.diff, 5.2 KB (added by Anssi Kääriäinen, 13 years ago)
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index d22a158..1ca984d 100644
    a b class RawQuerySet(object):  
    12991299        self.translations = translations or {}
    13001300
    13011301    def __iter__(self):
    1302         for row in self.query:
    1303             yield self.transform_results(row)
     1302        # Mapping of attrnames to row column positions. Used for constructing
     1303        # the model using kwargs, needed when not all model's fields are
     1304        # present in the query.
     1305        model_init_field_names = {}
     1306        # A list of tuples of (column name, column position). Used for
     1307        # annotation fields.
     1308        annotation_fields = []
     1309
     1310        # Cache some things for performance reasons outside the loop.
     1311        db = self.db
     1312        compiler = connections[db].ops.compiler('SQLCompiler')(self.query, connections[db], db)
     1313        need_resolv_columns = hasattr(compiler, 'resolve_columns')
     1314
     1315        # Find out which columns are model's fields, and which ones should be
     1316        # annotated to the model.
     1317        for pos, column in enumerate(self.columns):
     1318            if column in self.model_fields.keys():
     1319                model_init_field_names[self.model_fields[column].attname] = pos
     1320            else:
     1321                annotation_fields.append((column, pos))
     1322
     1323        # Find out which model's fields are not present in the query.
     1324        skip = set()
     1325        for field in self.model._meta.fields:
     1326            if field.attname not in model_init_field_names:
     1327                skip.add(field.attname)
     1328        if skip:
     1329            if self.model._meta.pk.attname in skip:
     1330                raise InvalidQuery('Raw query must include the primary key')
     1331            model_cls = deferred_class_factory(self.model, skip)
     1332        else:
     1333            model_cls = self.model
     1334            # All model's fields are present in the query. So, it is possible
     1335            # to use *args based model instantation. For each field of the model,
     1336            # record the query column position matching that field.
     1337            model_init_field_pos = []
     1338            for field in self.model._meta.fields:
     1339                model_init_field_pos.append(model_init_field_names[field.attname])
     1340        if need_resolv_columns:
     1341            fields = [self.model_fields.get(c, None) for c in self.columns]
     1342        # Begin looping through the query values.
     1343        for values in self.query:
     1344            if need_resolv_columns:
     1345                values = compiler.resolve_columns(values, fields)
     1346            # Associate fields to values
     1347            if skip:
     1348                model_init_kwargs = {}
     1349                for attname, pos in model_init_field_names.iteritems():
     1350                    model_init_kwargs[attname] = values[pos]
     1351                instance = model_cls(**model_init_kwargs)
     1352            else:
     1353                model_init_args = [values[pos] for pos in model_init_field_pos]
     1354                instance = model_cls(*model_init_args)
     1355            if annotation_fields:
     1356                for column, pos in annotation_fields:
     1357                    setattr(instance, column, values[pos])
     1358
     1359            instance._state.db = db
     1360            instance._state.adding = False
     1361
     1362            yield instance
    13041363
    13051364    def __repr__(self):
    13061365        return "<RawQuerySet: %r>" % (self.raw_query % self.params)
    class RawQuerySet(object):  
    13551414                self._model_fields[converter(column)] = field
    13561415        return self._model_fields
    13571416
    1358     def transform_results(self, values):
    1359         model_init_kwargs = {}
    1360         annotations = ()
    1361 
    1362         # Perform database backend type resolution
    1363         connection = connections[self.db]
    1364         compiler = connection.ops.compiler('SQLCompiler')(self.query, connection, self.db)
    1365         if hasattr(compiler, 'resolve_columns'):
    1366             fields = [self.model_fields.get(c,None) for c in self.columns]
    1367             values = compiler.resolve_columns(values, fields)
    1368 
    1369         # Associate fields to values
    1370         for pos, value in enumerate(values):
    1371             column = self.columns[pos]
    1372 
    1373             # Separate properties from annotations
    1374             if column in self.model_fields.keys():
    1375                 model_init_kwargs[self.model_fields[column].attname] = value
    1376             else:
    1377                 annotations += (column, value),
    1378 
    1379         # Construct model instance and apply annotations
    1380         skip = set()
    1381         for field in self.model._meta.fields:
    1382             if field.attname not in model_init_kwargs.keys():
    1383                 skip.add(field.attname)
    1384 
    1385         if skip:
    1386             if self.model._meta.pk.attname in skip:
    1387                 raise InvalidQuery('Raw query must include the primary key')
    1388             model_cls = deferred_class_factory(self.model, skip)
    1389         else:
    1390             model_cls = self.model
    1391 
    1392         instance = model_cls(**model_init_kwargs)
    1393 
    1394         for field, value in annotations:
    1395             setattr(instance, field, value)
    1396 
    1397         instance._state.db = self.query.using
    1398         instance._state.adding = False
    1399 
    1400         return instance
    1401 
    14021417def insert_query(model, values, return_id=False, raw_values=False, using=None):
    14031418    """
    14041419    Inserts a new record for the given model. This provides an interface to
Back to Top