diff --git a/apps/acls/managers.py b/apps/acls/managers.py index 6d674bbc59..0b22db3cbd 100644 --- a/apps/acls/managers.py +++ b/apps/acls/managers.py @@ -95,11 +95,20 @@ class AccessEntryManager(models.Manager): raise PermissionDenied(ugettext(u'Insufficient access.')) - def get_allowed_class_objects(self, permission, actor, cls): + def get_allowed_class_objects(self, permission, actor, cls, related=None): + logger.debug('related: %s' % related) + actor_type = ContentType.objects.get_for_model(actor) content_type = ContentType.objects.get_for_model(cls) - - return (obj.content_object for obj in self.model.objects.filter(holder_type=actor_type, holder_id=actor.pk, content_type=content_type, permission=permission.get_stored_permission)) + if related: + master_list = [obj.content_object for obj in self.model.objects.select_related().filter(holder_type=actor_type, holder_id=actor.pk, permission=permission.get_stored_permission)] + logger.debug('master_list: %s' % master_list) + # TODO: update to use Q objects and check performance diff + # kwargs = {'%s__in' % related: master_list} + # Q(**kwargs) + return (obj for obj in cls.objects.all() if getattr(obj, related) in master_list) + else: + return (obj.content_object for obj in self.model.objects.filter(holder_type=actor_type, holder_id=actor.pk, content_type=content_type, permission=permission.get_stored_permission)) def get_acl_url(self, obj): content_type = ContentType.objects.get_for_model(obj) @@ -132,7 +141,7 @@ class AccessEntryManager(models.Manager): content_type = ContentType.objects.get_for_model(obj) return (access.permission for access in self.model.objects.filter(content_type=content_type, object_id=obj.pk, holder_type=actor_type, holder_id=actor.pk)) - def filter_objects_by_access(self, permission, actor, object_list, exception_on_empty=False): + def filter_objects_by_access(self, permission, actor, object_list, exception_on_empty=False, related=None): logger.debug('exception_on_empty: %s' % exception_on_empty) logger.debug('object_list: %s' % object_list) @@ -150,7 +159,7 @@ class AccessEntryManager(models.Manager): try: # Try to process as a QuerySet - qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0])]) + qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)]) logger.debug('qs: %s' % qs) if qs.count() == 0 and exception_on_empty == True: @@ -158,13 +167,13 @@ class AccessEntryManager(models.Manager): return qs except AttributeError: - # Fallback to a list filtered list - obj_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0]))) - logger.debug('obj_list: %s' % obj_list) - if len(obj_list) == 0 and exception_on_empty == True: + # Fallback to a filtered list + object_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related))) + logger.debug('object_list: %s' % object_list) + if len(object_list) == 0 and exception_on_empty == True: raise PermissionDenied - return obj_list + return object_list class DefaultAccessEntryManager(models.Manager):