Change populate_relationships() for many-to-one relationships to pull only the base object ID, and not a whole instance of the base model, from each related model. Pulling the whole base model involves an unnecessary DB query each time, since the initial query for related models already includes all the base model IDs, and that's all we're interested in. I don't know if this was new with Django 1.0 or not, but it was massively slowing down populate_relationships() for large queries, commonly encountered with get_detailed_test_views.
My test query went from ~55s to ~2s with this change.
Signed-off-by: Steve Howard <showard@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@3579 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/frontend/afe/model_logic.py b/frontend/afe/model_logic.py
index 3e83abb..d26aaab 100644
--- a/frontend/afe/model_logic.py
+++ b/frontend/afe/model_logic.py
@@ -276,10 +276,12 @@
filter_data = {foreign_key_field.name + '__pk__in':
base_objects_by_id.keys()}
for related_object in related_model.objects.filter(**filter_data):
- fresh_base_object = getattr(related_object, foreign_key_field.name)
- # lookup base object in the dict -- we need to return instances from
- # the dict, not fresh instances of the same models
- base_object = base_objects_by_id[fresh_base_object._get_pk_val()]
+ # lookup base object in the dict, rather than grabbing it from the
+ # related object. we need to return instances from the dict, not
+ # fresh instances of the same models (and grabbing model instances
+ # from the related models incurs a DB query each time).
+ base_object_id = getattr(related_object, foreign_key_field.attname)
+ base_object = base_objects_by_id[base_object_id]
yield base_object, related_object