diff --git a/src/objects/manager.py b/src/objects/manager.py index ea0d3ebf8a..fae02e6a00 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -1,6 +1,7 @@ """ Custom manager for Objects. """ +from itertools import chain from django.db.models import Q from django.conf import settings from django.db.models.fields import exceptions @@ -117,16 +118,16 @@ class ObjectManager(TypedObjectManager): #q = self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name) & Q(objattribute__db_value=attribute_value)) #return list(q) - #if isinstance(attribute_value, (basestring, int, float, bool, long)): - return self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name, db_attributes__db_value=attribute_value)) - #else: - # # We have to loop for safety since the referenced lookup gives deepcopy error if attribute value is an object. - # global _ATTR - # if not _ATTR: - # from src.typeclasses.models import Attribute as _ATTR - # cands = list(self.filter(cand_restriction & type_restriction & Q(objattribute__db_key=attribute_name))) - # return [_ATTR. - # return [_GA(attr, "db_obj") for attr in _OBJATTR.objects.filter(db_obj__in=cands, db_value=attribute_value)] + if isinstance(attribute_value, (basestring, int, float, bool, long)): + return self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name, db_attributes__db_value=attribute_value)) + else: + # We have to loop for safety since the referenced lookup gives deepcopy error if attribute value is an object. + global _ATTR + if not _ATTR: + from src.typeclasses.models import Attribute as _ATTR + cands = list(self.filter(cand_restriction & type_restriction & Q(db_attributes__db_key=attribute_name))) + results = [attr.db_objects.all() for attr in _ATTR.objects.filter(db_objects__in=cands, db_value=attribute_value)] + return chain(*results) @returns_typeclass_list def get_objs_with_db_property(self, property_name, candidates=None): diff --git a/src/scripts/admin.py b/src/scripts/admin.py index da8a492ecd..89e1413e76 100644 --- a/src/scripts/admin.py +++ b/src/scripts/admin.py @@ -21,6 +21,7 @@ class ScriptDBAdmin(admin.ModelAdmin): save_as = True save_on_top = True list_select_related = True + raw_id_fields = ('db_obj',) fieldsets = ( (None, { diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index ea99c0bb11..e3ad91f99b 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -596,7 +596,8 @@ class TypedObject(SharedMemoryModel): help_text="locks limit access to an entity. A lock is defined as a 'lock string' on the form 'type:lockfunctions', defining what functionality is locked and how to determine access. Not defining a lock means no access is granted.") # many2many relationships db_attributes = models.ManyToManyField(Attribute, null=True, - help_text='attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).') + help_text='attributes on this object. An attribute can hold any pickle-able python object (see docs for special cases).', + related_name='db_objects') db_liteattributes = models.ManyToManyField(LiteAttribute, null=True, help_text='liteattributes on this object. A LiteAttribute holds a key, a category and a string field for simple lookups.') db_tags = models.ManyToManyField(Tag, null=True, @@ -1158,7 +1159,7 @@ class TypedObject(SharedMemoryModel): attribute_name: (str) The attribute's name. default: What to return if no attribute is found - raise_exception (bool) - raise an eception if no object exists instead of returning default. + raise_exception (bool) - raise an exception if no object exists instead of returning default. """ attr_obj = get_attr_cache(self, attribute_name) if not attr_obj: diff --git a/src/utils/picklefield.py b/src/utils/picklefield.py index bcb513c819..dc33464ee3 100644 --- a/src/utils/picklefield.py +++ b/src/utils/picklefield.py @@ -217,14 +217,8 @@ class PickledObjectField(_get_subfield_superclass()): raise TypeError('Lookup type %s is not supported.' % lookup_type) # The Field model already calls get_db_prep_value before doing the # actual lookup, so all we need to do is limit the lookup types. - try: - return super(PickledObjectField, self).get_db_prep_lookup( - lookup_type, value, connection=connection, prepared=prepared) - except TypeError: - # Try not to break on older versions of Django, where the - # `connection` and `prepared` parameters are not available. - return super(PickledObjectField, self).get_db_prep_lookup( - lookup_type, value) + return super(PickledObjectField, self).get_db_prep_lookup( + lookup_type, value, connection=connection, prepared=prepared) # South support; see http://south.aeracode.org/docs/tutorial/part4.html#simple-inheritance