summaryrefslogtreecommitdiff
path: root/django/db/models/query.py
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2009-04-04 05:34:23 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2009-04-04 05:34:23 +0000
commit0a89a57ffc491f2d1ff9a19e792739f67a945be3 (patch)
tree30ae16f25deb0e011dba8c9f742bf49c4f2390a3 /django/db/models/query.py
parentdded5f52cc1dbe0e58b64a3217e12e72da7bed23 (diff)
downloaddjango-0a89a57ffc491f2d1ff9a19e792739f67a945be3.tar.gz
Fixed deferred fields and select_related() interaction.
Loading related models when some fields were deferred was resulting in incorrect offsets being used into the results row, causing the wrong data to be assigned to attributes. Refs #10710. This fixes the first of two bugs reported there. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10383 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/db/models/query.py')
-rw-r--r--django/db/models/query.py49
1 files changed, 26 insertions, 23 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 9dcc031a39..9323e9b36b 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -908,31 +908,35 @@ def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
return None
restricted = requested is not None
- index_end = index_start + len(klass._meta.fields)
- fields = row[index_start:index_end]
- if not [x for x in fields if x is not None]:
- # If we only have a list of Nones, there was not related object.
- obj = None
- else:
- load_fields = only_load and only_load.get(klass) or None
- if load_fields:
- # Handle deferred fields.
- skip = set()
- init_list = []
- pk_val = fields[klass._meta.pk_index()]
- for field in klass._meta.fields:
- if field.name not in load_fields:
- skip.add(field.name)
- else:
- init_list.append(field.attname)
- if skip:
- klass = deferred_class_factory(klass, skip)
- obj = klass(**dict(zip(init_list, fields)))
+ load_fields = only_load and only_load.get(klass) or None
+ if load_fields:
+ # Handle deferred fields.
+ skip = set()
+ init_list = []
+ pk_val = row[index_start + klass._meta.pk_index()]
+ for field in klass._meta.fields:
+ if field.name not in load_fields:
+ skip.add(field.name)
else:
- obj = klass(*fields)
+ init_list.append(field.attname)
+ field_count = len(init_list)
+ fields = row[index_start : index_start + field_count]
+ if fields == (None,) * field_count:
+ obj = None
+ elif skip:
+ klass = deferred_class_factory(klass, skip)
+ obj = klass(**dict(zip(init_list, fields)))
else:
obj = klass(*fields)
- index_end += offset
+ else:
+ field_count = len(klass._meta.fields)
+ fields = row[index_start : index_start + field_count]
+ if fields == (None,) * field_count:
+ obj = None
+ else:
+ obj = klass(*fields)
+
+ index_end = index_start + field_count + offset
for f in klass._meta.fields:
if not select_related_descend(f, restricted, requested):
continue
@@ -948,7 +952,6 @@ def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
setattr(obj, f.get_cache_name(), rel_obj)
return obj, index_end
-
def delete_objects(seen_objs):
"""
Iterate through a list of seen classes, and remove any instances that are