【问题标题】:How to filter user related records with permissions in Django Rest Framework如何在 Django Rest Framework 中过滤具有权限的用户相关记录
【发布时间】:2016-02-23 15:18:32
【问题描述】:

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

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

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    没有现成的方式来使用魔杖处理此类权限。虽然有一些库可以处理对象级权限,但请检查django-guardian,因为它与 Django rest Framework 有很好的接口。

    处理此问题的一个好方法是将 django-guardian 的功能与@ilse2005 的答案所述的自定义get_queryset() 方法结合起来。这会处理您的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)
    

    这也适用于 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
    

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

    permission_classes = BlackListPermission

    【讨论】:

      【解决方案2】:

      您可以通过覆盖ModelViewSetget_queryset 方法来做到这一点:

      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)
      

      这假设您的FooModel 有一个ForeignKey 属性,称为ownerUserModel

      编辑:

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

      【讨论】:

        猜你喜欢
        • 2020-02-20
        • 2018-11-11
        • 1970-01-01
        • 2016-06-23
        • 2018-12-06
        • 2023-03-03
        • 2021-12-13
        • 2014-03-21
        • 2018-04-12
        相关资源
        最近更新 更多