在django rest框架中对单独的对象和对象列表应用权限之间的区别

时间:2016-10-03 19:38:13

标签: python django permissions django-rest-framework

在我的代码中,权限对象和对象列表的结果不同。

我们假设我们有一个User模型:

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)

和db中的两行:

1. name = "Dennis", profile_status = "private" # (not "public")
2. name = "Robert", profile_status = "private" # (not "public")

和视图集:

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]

IsProfileAccessStatus('public') django权限返回True如果对象profile_status等于公共'

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

后端返回/api/users/处的用户和/api/users/:name/处的特定用户。

不同的输出

On /api/users/Dennis/ drf根据IsProfileAccessStatus('public')权限返回异常。没关系。

但对于/api/users/,它会返回两个对象:

[
  { "name": "Dennis", "profile_status": "private" },
  { "name": "Robert", "profile_status": "private" }
]

所以问题是为什么用这种方式使用django权限?为什么不为每个实例应用drf权限?

谢谢!

1 个答案:

答案 0 :(得分:1)

为每个用户执行此操作的计算成本很高。想象一下,如果你有成千上万的人。在docs

  

对象级权限的限制

     

出于性能原因,通用视图不会自动应用   返回时查询集中每个实例的对象级权限   对象列表。

     

通常,当您使用对象级权限时,您也会想要   适当地过滤查询集,以确保用户只有   对可以查看的实例的可见性。

解决方法可能只是覆盖列表视图并使用.filter(profile_status__exact='public'