title: Django REST framework object level permissions
body: <p>I am using Django REST Framework to access a resource 'user'.</p>
  <p>As user information is personal, I do not want a GET request to list every user on the system, UNLESS they are an admin.</p>
  <p>If the user specifies their id, and they are logged in, I would like them to be able to view their details and amend them (PUT POST DELETE) if required.</p>
  <p>So in summary, dis-allow GET method for anyone who isn't an admin and allow GET POST DELETE PUT on logged-in users when viewing their information.</p>
  <p>I created the custom permission class:</p>
  <pre><code>class UserPermissions(permissions.BasePermission):
      &quot;&quot;&quot;
      Owners of the object or admins can do anything.
      Everyone else can do nothing.
  &quot;&quot;&quot;
      
      def has_permission(self, request, view):
          # if admin: True otherwise False
      def has_object_permission(self, request, view, obj):
          # if request.user is the same user that is contained within the obj then allow
  </code></pre>
  <p>This didn't work. After some debugging I found that it checks <code>has_permission</code> first, THEN checks <code>has_object_permission</code>. So if we don't get past that first hurdle GET <code>/user/</code>, then it won't even consider the next GET <code>/user/id</code>.</p>
  <p>How I would go about getting this to work?</p>
  <p>I was using ModelViewSets.</p>
  <p>But if you split the List functionality with the Detail then you can give them separate permission classes:</p>
  <pre><code>class UserList(generics.ListCreateAPIView):
      queryset = User.objects.all()
      serializer_class = UserSerializer
      permission_classes=(UserPermissionsAll,)
  
  class UserDetail(generics.RetrieveUpdateDestroyAPIView):
      queryset = User.objects.all()
      serializer_class = UserSerializer
      permission_classes=(UserPermissionsObj,)
  
  class UserPermissionsAll(permissions.BasePermission):
  &quot;&quot;&quot;
  Owners of the object or admins can do anything.
  Everyone else can do nothing.
  &quot;&quot;&quot;
  
      def has_permission(self, request, view):
          if request.user.is_staff:
              return True
          else:
              return False
  
  class UserPermissionsObj(permissions.BasePermission):
  &quot;&quot;&quot;
  Owners of the object or admins can do anything.
  Everyone else can do nothing.
  &quot;&quot;&quot;
  
      def has_object_permission(self, request, view, obj):
          if request.user.is_staff:
              return True
  
          return obj == request.user
  </code></pre>