Django REST Permissions on Nested Routes
Asked Answered
P

1

9

I am using the Django REST framework with the nested router extension. One of my routes looks like: companies/$company/locations/$location where $company and $location are slug variables.

I want to allow users to POST to this URL: companies/$company/locations/ to add new locations. I want to make sure that the user doing the POST has the correction permissions for the company he is POSTing to. I currently use django-guardian for my object level permissions. The POST message contains only the name of the new location it does not contain the name of the company as that can be inferred from the URL. I am having a hard time correctly enforcing the permissions in this case. I had been setting the company field of the new Location object from the viewset's pre_save method but this is too late for the permission check to be applied.

What is the best way to enforce this?

In the case there the user does include the company in the POST, I can validate the company by adding the following to the viewset:

def get_queryset(self):
    parent = super(LocationViewSet, self).get_queryset()    
    return parent.filter(company__slug=self.kwargs['company_slug'])
Publication answered 24/6, 2014 at 3:27 Comment(2)
@alex how did you get company slug in the pre_save method? I am also looking for the answer to your actual questionDeformation
Can you post the urls and views and serializer ?Sike
G
0

Well, I actually found a rather ugly way to do this, retrieving the parent object and checking it's belonging against request's user.

def create(self, request, *args, **kwargs):
    request.data['catspad'] = kwargs['catspad_pk']
    if not Catspad.objects.get(id=kwargs['catspad_pk']).owner == request.user:
        return Response(status=HTTP_401_UNAUTHORIZED)
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    return Response(serializer.data, status=HTTP_201_CREATED, headers=headers)
Giamo answered 10/6, 2016 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.