当前位置:  开发笔记 > 编程语言 > 正文

用于在viewset中创建的Django-rest-framework权限

如何解决《用于在viewset中创建的Django-rest-framework权限》经验,为你挑选了2个好方法。

我正在尝试创建一个REST API并且卡在用户注册中:基本上我需要在注册之前拥有访问令牌.

这是观点:

class UserViewSet(viewsets.ModelViewSet):

    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def metadata(self, request):
        """
        Don't include the view description in OPTIONS responses.
        """
        data = super(UserViewSet, self).metadata(request)
        return data

    def create(self, request):
        serializer = self.get_serializer(data=request.DATA, files=request.FILES)

        if serializer.is_valid():
            self.pre_save(serializer.object)
            self.object = serializer.save(force_insert=True)
            self.post_save(self.object, created=True)
            self.object.set_password(self.object.password)
            self.object.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是解决方法:

@api_view(['POST'])
@permission_classes((AllowAny,))
@csrf_exempt
def create_auth(request, format=None):
    data = JSONParser().parse(request)
    serialized = UserSerializer(data=data)

    if serialized.is_valid():
        user = User.objects.create_user(
            serialized.init_data['email'],
            serialized.init_data['username'],
            serialized.init_data['password'],
        )
        user.groups = serialized.init_data['groups']

        user.save()

        serialized_user = UserSerializer(user)
        return Response(serialized_user.data, status=status.HTTP_201_CREATED, headers={"Access-Control-Allow-Origin": "http://127.0.0.1:8000/"})
    else:
        return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST, headers={"Access-Control-Allow-Origin": "http://127.0.0.1:8000/"})

我的问题是:如何在UserViewSet中指定对于创建我不需要凭据?或者指定自定义身份验证方法?我不想更改整个视图集的身份验证/权限类.

谢谢,阿迪

编辑 澄清:应该允许未注册的用户发布注册数据,不应该允许任何其他内容.经过身份验证的用户可以获取用户列表并更新自己的配置文件...这是默认行为.这就是AllowAny 不是一个选项的原因.在我看来,适当的地方是创建功能,但我没有得到我应该覆盖的东西.



1> argaen..:

自定义get_queryset方法:

def get_queryset(self):
    if self.request.user.is_superuser:
        return User.objects.all()
    else:
        return User.objects.filter(id=self.request.user.id)

这样,经过身份验证的用户只能检索,修改或删除自己的对象.

指定经过permission_classes = (AllowAny,)身份验证的用户可以创建新用户.

编辑:评论的进一步解释

以这种方式自定义get_queryset方法意味着:

    是的,未经过身份验证的用户可以发送GET请求以检索用户列表,但它将为空,因为返回User.objects.filter(id = self.request.user.id)可确保仅返回有关经过身份验证的用户的信息.

    这同样适用于其他方法,如果经过身份验证的用户尝试删除另一个用户对象,则会返回一个详细信息:未找到(因为它尝试访问的用户不在查询集中).

    经过身份验证的用户可以对用户对象执行任何操作.


不,因为注册用户只能使用自己的对象而不是其他对象,视图中的get_queryset方法确保此行:返回User.objects.filter(id = self.request.user.id).
以这种方式自定义get_queryset方法意味着以下内容:**1**是的,未经过身份验证的用户可以发送GET请求以检索用户列表,但它将是**空**因为`return User.objects.filter( id = self.request.user.id)`确保仅返回有关经过身份验证的用户的信息.**2**这同样适用于其他方法,如果经过身份验证的用户尝试删除另一个用户对象,则会返回一个详细信息:未找到(因为它尝试访问的用户不在查询集中).**3**经过身份验证的用户可以为他们的*用户对象做任何他们想做的事情.

2> devonbleibtr..:

您可以利用Django REST Framework定义自定义权限的能力.您可以在自定义类中指定a has_permissionhas_object_permission.除了发布到创建端点之外,这将为您提供向anon用户投掷403s的预期行为.它可能看起来像:

class IsAnonCreate(permissions.BasePermission):
    def has_permission(self, request, view):
        if request.method == "POST" and not request.user.is_authenticated():
            return True
        elif not request.user.is_authenticated() and request.method != "POST":
            return False
        elif request.method in permissions.SAFE_METHODS:
            return True

        return False

    def has_object_permission(self, request, view, obj):
        if not request.user.is_authenticated():
            return False
        if request.method in permissions.SAFE_METHODS:
            return True

        return obj.username == request.user.username

然后,您可以根据需要为经过身份验证的用户添加一些自定义处理.

然后,您需要做的就是将权限类添加到您的ModelViewSet:

class UserViewSet(viewsets.ModelViewSet):

    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (IsAnonCreate, )

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有