Как я могу получить все объекты, к которым у пользователя есть определенные разрешения в django guardian? - PullRequest
2 голосов
/ 12 января 2011

В настоящее время я делаю действительно неуклюжий цикл по всем объектам, но он будет медленным:

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)

Я полагаю, что должен быть способ просто получить все объекты, для которых у этого пользователя есть разрешения.

Ответы [ 3 ]

9 голосов
/ 16 января 2011

несколько дней назад произошло обновление с новой функцией ярлыка "get_objects_for_user". Если вы используете старую версию Guardian и не можете обновить ее, вы можете просто скопировать коды оттуда.

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

Это всегда делает 3 запроса. Если вы зададите для параметра «use_groups» значение False, то будут выполнены 2 запроса, однако возвращенный набор запросов не будет содержать объекты, для которых группы пользователей имеют разрешения. Вы также можете указать список кодовых имен, а не одно разрешение при необходимости. Подробнее здесь .

1 голос
/ 12 января 2011

Если вы хотите резко ускориться, почему бы не попросить базу данных вытянуть только те объекты, которые вам интересны,

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

Это должно дать вам все пользовательские объекты, на которые у пользователя есть разрешение.и их пользователь и группа.

1 голос
/ 12 января 2011

Вы знаете, что вы создаете новый экземпляр ObjectPermissionChecker в каждом цикле, в то время как вам не нужно это делать, и я предлагаю сделать что-то подобное, что может быть более синтаксически сахарным и, возможно, может дать вам большескорость

checker = ObjectPermissionChecker(request.user)

videos = Video.objects.all()

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

Для вашего вопроса вы можете использовать django-object-permissions посмотрите здесь для более подробной информации о том, как использовать.

...