Django Rest Framework将用户数据视图限制为管理员和自己的用户

时间:2017-06-13 23:52:41

标签: django django-rest-framework

我正在使用Django和DRF,我想检查用户(常规用户)在经过身份验证后是否可以查看自己的个人资料而且只能查看(没有其他用户&#39) ; S)

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
    model = User
    fields = ('id', 'url', 'username', 'password', 'email', 'groups', 'is_staff')

def create(self, validated_data):
    user = super().create(validated_data)
    user.set_password(validated_data['password'])
    user.save()
    return user

Views.py

class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = (IsUser,)

permissions.py

class IsUser(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""

def has_permission(self, request, view, obj):
    # View or Write permissions are only allowed to the owner of the snippet.
    return obj.owner == request.user

这显然不起作用,因为错了。但我无法弄清楚如何允许用户查看:

http://127.0.0.1:8000/api/users/7

仅限其管理员或执行请求的同一用户。

和: http://127.0.0.1:8000/api/users/ 只有它是管理员。

谢谢!

4 个答案:

答案 0 :(得分:5)

class UserViewSet(ModelViewSet):
    queryset = Message.objects.all()
    serializer_class = UserSerializer

    def get_permissions(self):
        if self.action == 'list':
            self.permission_classes = [IsSuperUser, ]
        elif self.action == 'retrieve':
            self.permission_classes = [IsUser]
        return super(self.__class__, self).get_permissions()

class IsSuperUser(BasePermission):

    def has_permission(self, request, view):
        return request.user and request.user.is_superuser

class IsUser(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.user:
            if request.user.is_superuser:
                return True
            else:
                return obj == request.user
        else:
            return False

覆盖UserViewSet的列表和检索方法可能是最简单的方法。

答案 1 :(得分:1)

我很抱歉,因为我没有足够的代表来补充Ykh的答案

views.py

class UserViewSet(ModelViewSet):
    queryset = Message.objects.all()
    serializer_class = UserSerializer

    def get_permissions(self):
        # Overrides to tightest security: Only superuser can create, update, partial update, destroy, list
        self.permission_classes = [IsSuperUser]

        # Allow only by explicit exception
        if self.action == 'retrieve':
            self.permission_classes = [IsOwner]

        return super(self.__class__, self).get_permissions()

permissions.py

class IsSuperUser(BasePermission):

    def has_permission(self, request, view):
        return request.user and request.user.is_superuser


class IsOwner(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.user:
            if request.user.is_superuser:
                return True
            else:
                return obj.owner == request.user
        else:
            return False

注意:obj.owner否则,如果您不是超级用户,将始终被拒绝。

谢谢您的基本答案。

答案 2 :(得分:0)

IsUser权限中添加额外的支票。

if request.method == permissions.SAFE_METHOD:
    return True

答案 3 :(得分:0)

像示例一样,默认授权列表,只为超级用户编辑

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated, IsAdminUser


class CsrfExemptSessionAuthentication(SessionAuthentication):
    def enforce_csrf(self, request):
        return  # To not perform the csrf check previously happening


class OnlyListAvaliableMixin:
    authentication_classes = (CsrfExemptSessionAuthentication,)

    def get_permissions(self):
        permission_classes = [IsAuthenticated] if self.action == 'list' else [IsAdminUser] # noqa
        return [permission() for permission in permission_classes]


# Example to use
class ListView(OnlyListAvaliableMixin, viewsets.ModelViewSet, ):
    # premission_classes = (IsAdminUser,)
    queryset = CarMark.objects.all()
    serializer_class = ListViewSerializer