I have two Django Model
s of the form:
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)
I am using django-guardian
to enforce object level permissions. The real application has a very large number of nested objects, and it was found that the write performance for creating all of the permission objects for every nested object was prohibitively slow. So instead, User
s are granted permissions to the top level object (Car
in this toy example).
On REST endpoints that access Wheel
, the Django REST Framework permissions are checked by walking the foreign key upwards (in this case Wheel.car
) to verify if a User
should have access to a particular Wheel
.
How could get_objects_for_user
be used to get all of the Wheel
s for which a User
has the appropriate permission for its parent Car
?
Specifically trying to override django-rest-framework-guardian
's ObjectPermissionsFilter.filter_queryset
to support filtering objects based on the permissions of one of their ForeignKey
s.
I was able to get this to work by defining this Filter
for use with the 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)