The difference between applying permissions to separate object and list of objects in django rest framework
<p>In my code permissions result differently to object and list of objects.</p>

<p>Let's say we have one model of <code>User</code>:</p>

<pre><code>class User(auth.AbstractBaseUser, auth.PermissionsMixin):
    name = models.CharField(max_length=255, blank=True, null=True)
    profile_status = models.CharField(max_length=255, blank=True, null=True)
</code></pre>

<p>and two rows in db:</p>

<pre><code>1. name = "Dennis", profile_status = "private" # (not "public")
2. name = "Robert", profile_status = "private" # (not "public")
</code></pre>

<p>and the viewset:</p>

<pre><code>class UsersViewSet(viewsets.CreateListRetrieveUpdateViewSet):
    queryset = models.User.objects.all()            # doesn't matter...
    serializer_class = serializers.UserSerializer   # doesn't matter...
    filter_class = filters.UsersFilterSet           # doesn't matter...
    permission_classes = [IsProfileAccessStatus('public'),
                          IsReadOnly]
</code></pre>

<p><code>IsProfileAccessStatus('public')</code> django permission returns <code>True</code> if object's <code>profile_status</code> equals 'public':</p>

<pre><code>def IsProfileAccessStatus(access_status=''):

    class IsProfileStatusOf(BasePermission):
        def has_object_permission(self, request, view, obj):
            return hasattr(obj, 'profile_status') and \
                   obj.profile_status== access_status

    return IsProfileStatusOf
</code></pre>

<p>Back end returns users at <code>/api/users/</code> and speicific one at <code>/api/users/:name/</code>.</p>

<p><em>Different output</em></p>

<p>On <code>/api/users/Dennis/</code> drf returns exception according the <code>IsProfileAccessStatus('public')</code> permission. So it's okay.</p>

<p>But for <code>/api/users/</code> it returns both objects:</p>

<pre><code>[
  { "name": "Dennis", "profile_status": "private" },
  { "name": "Robert", "profile_status": "private" }
]
</code></pre>

<p>So the question is Why django permissions are used this way? Why drf permissions are not applied for every instance?</p>

<p>Thank you!</p>

<p>It is expensive computationally to do this for every user. Imagine if you had hundreds of thousands of them. In the <a href="http://www.django-rest-framework.org/api-guide/permissions/#limitations-of-object-level-permissions" rel="nofollow">docs</a>:</p>

<blockquote>
  <p><strong>Limitations of object level permissions</strong></p>
  
  <p>For performance reasons the generic views will not automatically apply
  object level permissions to each instance in a queryset when returning
  a list of objects.</p>
  
  <p>Often when you're using object level permissions you'll also want to
  filter the queryset appropriately, to ensure that users only have
  visibility onto instances that they are permitted to view.</p>
</blockquote>

<p>A work around is probably just to override the list view and use <code>.filter(profile_status__exact='public'</code></p>

python django permissions django-rest-framework