如何在序列化程序类上获取经过身份验证的用户以进行验证

时间:2015-04-08 20:33:52

标签: django django-rest-framework

我正在使用django-rest-framework处理项目。在我的API视图中,经过身份验证的用户可以创建其他用户。但是,只有五个。然后,如果有一个用户注册了五个用户,我想在达到限制的响应中发送给他。然后,我需要让我的序列化程序获得经过身份验证的用户,但是,我无法找到将其从我的ModelViewSet传递到序列化程序的方法。

这是我的代码:

查看:

class ChildUserViewSet(viewsets.ModelViewSet):
    serializer_class = ChildUserSerializer
    queryset = User.objects.all()

    authentication_classes = (
        TokenAuthentication,
    )
    permission_classes = (
        IsAuthenticated,
    )

    def perform_create(self, serializer):
        account_group = self.request.user.userprofile.get_account_group

        mobile_number = serializer.data.get('mobile_number')
        password = serializer.data.get('password')
        user = serializer.save()
        user.set_password(password)
        user.save()

        # Generate user profile
        UserProfile.objects.create(
            user=user,
            mobile_number=mobile_number,
            user_type=CHILD,
            related_account_group=account_group,
        )

串行:

class ChildUserSerializer(serializers.ModelSerializer):
    mobile_number = serializers.CharField()

    class Meta:
        model = User

        fields = (
            'first_name',
            'last_name',
            'email',
            'password',
            'mobile_number',
        )

    def validate(self, data):
        """
        Check that the start is before the stop.
        """
        # Get authenticated user for raise hit limit validation



    def validate_email(self, value):
        if User.objects.filter(email=value):
            raise serializers.ValidationError("This field must be unique.")
        return value

    def create(self, validated_data):
        username = generate_unique_username(
            u'{0}{1}'.format(
                validated_data['first_name'],
                validated_data['last_name'],
            )
        )

        user = User(
            username=username,
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
            email=validated_data['email'],
        )

        user.set_password(validated_data['password'])
        user.save()

        return user

然后,在我的序列化程序的def validate(self, data)函数中,我想获得当前经过身份验证的用户。

如何将request.user从我的APIView传递给我的序列化程序?

4 个答案:

答案 0 :(得分:10)

我找到了一种更简单的方法来实现这一目标!事实证明,Rest Framework的GenericAPIView基类(所有Rest Framework的通用View类都从中下降)includes a function called get_serializer_context()

def get_serializer_context(self):
    """
    Extra context provided to the serializer class.
    """
    return {
        'request': self.request,
        'format': self.format_kwarg,
        'view': self
    }

如您所见,返回的context对象包含View接收的相同request对象。然后,此对象将设置为when the serializer is initialized

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)

因此,要访问发出请求的用户,您只需在序列化程序的self.context['request'].user函数中调用validate_

class TemplateSerializer(serializers.ModelSerializer):
    def validate_parent(self, value):
        print(self.context['request'].user)

        return value

    class Meta:
        model = Template

最好的部分是你不必覆盖ModelViewSet中的任何内容,它们可以保持原样:

class TemplateViewSet(viewsets.ModelViewSet):
    serializer_class = TemplateSerializer
    permission_classes = [IsAdmin]

答案 1 :(得分:3)

您可以使用serializer = ChildUserSerializer(data, context={'request': request})将其他上下文传递给序列化程序。然后,您可以通过序列化验证方法中的request.user访问经过身份验证的用户。

答案 2 :(得分:2)

在djangorestframework> 3.2.4 rest_framework.generic.GenericAPIView类默认在序列化程序上下文中包含http请求。

因此,在序列化程序中,您可以通过以下方式访问它:self.context['request']和用户self.context['request'].user

所以你的ChildUserSerializer看起来像是:

class ChildUserSerializer(serializers.ModelSerializer):
    mobile_number = serializers.CharField()
    ....
    def validate(self, data):
        """
        Check that the start is before the stop.
        """
        # Get authenticated user for raise hit limit validation
        user = self.context['request'].user
        # do something with the user here
    def validate_email(self, value):
        if User.objects.filter(email=value):
            raise serializers.ValidationError("This field must be unique.")
        return value
    ...

答案 3 :(得分:1)

在初始化序列化工具时的视图中

serializer = ChildUserSerializer(data=request.DATA,context={'request':request})

,发送一个包含request的上下文。然后在函数调用中的Serializers中

request=self.context['request']

然后您可以访问request.user