如何在 Django Rest Framework 中过滤具有权限的用户相关记录

Ste*_*own 5 django django-rest-framework

我需要知道如何限制对经过身份验证的用户的访问,以便可以为以管理员身份登录的用户完整列出用户记录,而对于以用户身份登录的用户,只能列出、更新和创建他们的记录。

目前我正在使用serializers.ModelSerializer、viewsets.ModelViewSet 和permissions.BasePermission 但似乎进展不快。

ian*_*kit 6

没有现成的方法可以用魔杖处理此类权限。尽管有一些库可以处理对象级别权限,但请检查一下,django-guardian因为它与 Django Rest Framework 具有良好的接口。

处理这个问题的一个好方法是将 django-guardian 的功能与get_queryset()@ilse2005 的答案中描述的自定义方法结合起来。这会照顾您的listretrieve,并且更新和删除可以委托给django-guardian

class View(ModelViewSet):
    ...

    def get_queryset(self):
        if self.request.user.is_superuser:
            return FooModel.objects.all()
        return FooModel.objects.filter(owner=self.request.user)
Run Code Online (Sandbox Code Playgroud)

这也可以与 DRF 中的 APIView 和其他基于类的视图一起使用。

注意:如果您的 API 使用者依赖 HTTP 错误代码来表示此方法,则会抛出 404 not found 而不是 HTTP403(这是表示权限被拒绝的标准方式)。在这种情况下,建议编写自定义权限类。例如,以下 ip 黑名单权限类直接来自文档 - http://www.django-rest-framework.org/api-guide/permissions/

from rest_framework import permissions

class BlacklistPermission(permissions.BasePermission):
    """
    Global permission check for blacklisted IPs.
    """

    def has_permission(self, request, view):
        ip_addr = request.META['REMOTE_ADDR']
        blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
        return not blacklisted
Run Code Online (Sandbox Code Playgroud)

通过设置类变量在视图集中使用此类

permission_classes = BlackListPermission


ils*_*005 2

get_queryset您可以通过覆盖以下方法来做到这一点ModelViewSet

class View(ModelViewSet):
    ...

    def get_queryset(self):
        if self.request.user.is_superuser:
            return FooModel.objects.all()
        return FooModel.objects.filter(owner=self.request.user)
Run Code Online (Sandbox Code Playgroud)

这假设您有FooModel一个ForeignKey名为ownerUserModel

编辑:

上述方法仅适用于listretrieve。对于该update方法,您必须编写自定义权限。