Add related support to 'filter_objects_by_access' and 'get_allowed_class_objects' methods

This commit is contained in:
Roberto Rosario
2012-01-03 18:47:28 -04:00
parent 4ded57f27d
commit 1cd3c4e7d0

View File

@@ -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):