From c819cdc2a626cb1b95b0e42882ce488c1e4f6816 Mon Sep 17 00:00:00 2001 From: Griatch Date: Fri, 28 Sep 2012 00:02:31 +0200 Subject: [PATCH] Added a change to get_objs_with_attr_values that means simple python lookup values will be searched for directly in the database by pickling the input argument in the form used by Attributes. This should lead to a more efficient attrvalue lookup for larger databases (as long as value is a string, int or float and not a compound object, at which the lookup is continuously done in two steps filtering through the Attribute value mechanism. --- src/objects/manager.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/objects/manager.py b/src/objects/manager.py index f5e5825018..be42d47f55 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -1,6 +1,8 @@ """ Custom manager for Objects. """ +try: import cPickle as pickle +except ImportError: import pickle from django.db.models import Q from django.conf import settings #from django.contrib.auth.models import User @@ -8,10 +10,11 @@ from django.db.models.fields import exceptions from src.typeclasses.managers import TypedObjectManager from src.typeclasses.managers import returns_typeclass, returns_typeclass_list from src.utils import utils -from src.utils.utils import to_unicode, make_iter, string_partial_matching +from src.utils.utils import to_unicode, make_iter, string_partial_matching, to_str __all__ = ("ObjectManager",) _GA = object.__getattribute__ +_DUMPS = lambda inp: to_unicode(pickle.dumps(inp)) # Try to use a custom way to parse id-tagged multimatches. @@ -126,8 +129,13 @@ class ObjectManager(TypedObjectManager): not make sense to offer an "exact" type matching for this. """ cand_restriction = candidates and Q(db_obj__pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q() - attrs= self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name)) - return [attr.db_obj for attr in attrs if attribute_value == attr.value] + if type(attribute_value) in (basestring, int, float): + # simple attribute_value - do direct lookup + return self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name) & Q(db_value=_DUMPS(("simple", attribute_value)))) + else: + # go via attribute conversion + attrs= self.model.objattribute_set.related.model.objects.select_related("db_obj").filter(cand_restriction & Q(db_key=attribute_name)) + return [attr.db_obj for attr in attrs if attribute_value == attr.value] @returns_typeclass_list def get_objs_with_db_property(self, property_name, candidates=None):