【问题标题】:Django: How to limit model list access permission to its owner?Django:如何将模型列表访问权限限制为其所有者?
【发布时间】:2017-11-21 09:07:59
【问题描述】:

我有一个 django 模型,并且我希望该模型只能由其所有者(创建模型的用户)访问。所以我创建了一个权限类如下

class IsOwnerOnly(permissions.BasePermission):


def has_object_permission(self, request, view, obj):

    # Write permissions are only allowed to the owner of the snippet.
    return obj.owner == request.user

并将此权限应用于模型视图集

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = (IsOwnerOnly,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

在访问单个项目时它可以工作,但即使这样,每个经过身份验证的用户都可以访问项目列表。那么我怎样才能将项目的访问权限限制为只有它的所有者呢?

我已在设置页面中包含了 Tokenauthentication,如图所示

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (

    'rest_framework.authentication.TokenAuthentication',

),
}

项目看起来像

class Item(models.Model):

    name=models.CharField(max_length=30)
    address=models.TextField()
    owner = models.ForeignKey('auth.User', related_name='items', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

【问题讨论】:

  • return obj.owner == request.user, 是owner 模型Item 的字段吗?并且您无法控制所有者可以访问项目列表的人员,如果您需要覆盖has_permission 以班级IsOwnerOnly
  • 是的。这是一个字段
  • 我现在已经包含了它。请检查

标签: django django-models django-rest-framework django-authentication


【解决方案1】:

你无法通过所有者控制谁可以访问项目列表,如果你什么,你需要将 has_permission 覆盖为 IsOwnerOnly 类,例如:

class IsAuthenticatedOwner(permissions.BasePermission):
    def has_permission(self, request, view):
        # work when your access /item/
        if request.user and is_authenticated(request.user):
            if request.user.id in [1, 2, 3]:
                return True
            else:
                return False
        else:
            return False

    def has_object_permission(self, request, view, obj):
        # work when your access /item/item_id/
        # Instance must have an attribute named `owner`.
        return obj.owner == request.user

注意:has_permission在你访问时工作/item/(列表),has_object_permission在你访问时工作/item/item_id/(检索和更新)。

如果你想让用户只看到他创建的项目,简单如下:

class ItemsViewSet(ModelViewSet):
    queryset = Items.objects.all()
    serializer_class = ItemsSerializer
    permission_classes = (IsAuthenticated)

    def get_queryset(self):
        queryset = self.get_queryset().filter(owner=self.request.user)
        return queryset

【讨论】:

  • 好的。但我需要的是将权限仅限于其所有者
  • 我可以在访问 /item/item_id/ 时这样做,但不能在访问 /item/ 时这样做
  • 您希望您的用户只能看到他创建的项目吗?
  • 是的。这就是我想要的
【解决方案2】:

您可以在您的视图上覆盖方法get_queryset

class ItemViewSet(viewsets.ModelViewSet):

    queryset = Item.objects.all()
    serializer_class = ItemSerializer
    permission_classes = (IsOwnerOnly,)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

    def get_queryset(self):
        return self.queryset.filter(owner=self.request.user)

这样,list 方法(来自 ModelViewSet)将调用您的“get_queryset”来使用数据构建分页。

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 2011-09-14
    • 1970-01-01
    • 2019-02-15
    • 2019-05-13
    • 1970-01-01
    • 2018-12-24
    • 2016-06-05
    • 1970-01-01
    相关资源
    最近更新 更多