willcritchlow
willcritchlow

Reputation: 741

How can I get all objects a user has specific permissions to in django guardian?

I am currently doing a really clumsy loop over all the objects but that is going to get slow:

videos = Video.objects.all()
video_list = []
for video in videos:
    checker = ObjectPermissionChecker(request.user)
    if checker.has_perm('view_video', video):
        video_list.append(video)

I figure there must be a way of just getting all the objects for which this user has permissions.

Upvotes: 3

Views: 5077

Answers (3)

lukaszb
lukaszb

Reputation: 689

a few days ago there were update with new shortcut function called "get_objects_for_user". If you use older version of guardian and cannot update, you can simply copy codes from there.

from guardian.shortcuts import get_objects_for_user
...
videos = get_objects_for_user(request.user, "view_video", Video.objects.all())

It always do 3 queries. If you specify "use_groups" parameter to False, then 2 queries are performed however returned queryset wouldn't contain objects for which users' groups have permissions. You may also specify list of codenames, rather than single permission if needed. Read more here.

Upvotes: 10

milkypostman
milkypostman

Reputation: 3043

If you want to speed up drastically why not jus ask the database to pull only the objects you're interested in,

content_type = ContentType.objects.get_for_model(Video)
perm = Permissions.objects.get(codename='view_video'.split('.')[-1])

objs = set(
    UserObjectPermissions.objects.filter(user=user, permission=perm, content_type=content_type)
)

# and if you want to include groups
objs.update(
    set(
         GroupObjectPermissions.objects.filter(group__user=user, permission=perm, content_type=content_type)
    )
)

This should get you all user objects which the user has permission to through both their user and group.

Upvotes: 1

mouad
mouad

Reputation: 70059

You know that you are creating a new instance of ObjectPermissionChecker in each loop while you don't have to do that , and i will suggest to do something like this which can be more syntactically sugar and maybe can give you more speed

checker = ObjectPermissionChecker(request.user)

videos = Video.objects.all()

video_list = [video for video in videos if checker.has_perm('view_video', video)]

For your question you can use django-object-permissions look here for more detail about how to use.

Upvotes: 1

Related Questions