Как проверить права доступа django -guardian get_objects_for_user через ForeignKey - PullRequest
0 голосов
/ 20 марта 2020

У меня есть два Django Model s формы:

from django.db import models


class Car(models.Model):
    pass

class Wheel(models.Model):
    car = models.ForeignKey(Car, related_name='wheels', on_delete=models.CASCADE)

Я использую django-guardian для обеспечения прав доступа на уровне объекта. Реальное приложение имеет очень большое количество вложенных объектов, и было обнаружено, что производительность записи для создания всех объектов разрешений для каждого вложенного объекта была чрезмерно низкой. Таким образом, вместо User s предоставляются разрешения для объекта верхнего уровня (Car в этом игрушечном примере).

На конечных точках REST, которые обращаются к Wheel, Django REST Framework * Разрешения 1014 * проверяются путем перемещения внешнего ключа вверх (в данном случае Wheel.car), чтобы проверить, должен ли User иметь доступ к определенному Wheel.

Как можно get_objects_for_user используется для получения всех Wheel s, для которых User имеет соответствующее разрешение для своего родителя Car?

Специально пытается переопределить django-rest-framework-guardian ObjectPermissionsFilter.filter_queryset для поддержки фильтрации объектов на основе разрешений одного из их ForeignKey s.

1 Ответ

1 голос
/ 23 марта 2020

Я смог заставить это работать, определив Filter для использования с Wheel ViewSet filter_backends:

from rest_framework.filters import BaseFilterBackend


class CarObjectPermissionsFilter(BaseFilterBackend):
    perm_format = '%(app_label)s.view_%(model_name)s'

    def filter_queryset(self, request, queryset, view):
        permission = cls.perm_format % {
            'app_label': Car._meta.app_label,
            'model_name': Car._meta.model_name,
        }
        car_ids = get_objects_for_user(user, permission, Car.objects.values_list('pk', flat=True))
        return queryset.filter(car__in=car_ids)
...