Как разобрать запрос JSON данных для DRF Serializer в произвольном формате? - PullRequest
0 голосов
/ 07 января 2020

У меня есть сериализатор DRF, который выглядит следующим образом:

class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password = serializers.CharField()

    def validate(self, attrs):
        user = authenticate(username=attrs['email'], password=attrs['password'])
        if not user:
            raise serializers.ValidationError('Incorrect email or password.')
        if not user.is_active:
            raise serializers.ValidationError('User is disabled.')
        return user

Когда POST-запрос делается к API, он отправляет следующее JSON:

{
   "email": "user@example.com",
   "password": "somepassword"
}

Из-за определенных соглашений проекта I хотите, чтобы данные для десериализации были включены в объект request и отправлены в API в следующем формате:

{
    "request": {
        "email": "user@example.com",
        "password": "somepassword"
    }
}

Как я могу заставить сериализаторы DRF (как Serialize r, так и ModelSerializer) автоматически получать данные из блока request без записи дополнительного сериализатора с вложенным LoginSerializer?:

class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password = serializers.CharField()

    def validate(self, attrs):
        user = authenticate(username=attrs['email'], password=attrs['password'])
        if not user:
            raise serializers.ValidationError('Incorrect email or password.')
        if not user.is_active:
            raise serializers.ValidationError('User is disabled.')
        return user


class LoginRequestSerializer(serializers.Serializer):
    request = LoginSerializer()

Есть ли какой-нибудь тип RequestRenderer, который мне нужно реализовать в моем APIView?

1 Ответ

1 голос
/ 07 января 2020

Вы захотите использовать .to_internal_value метод:

https://www.django-rest-framework.org/api-guide/serializers/#overriding -сериализация-и-десериализация-поведение

Как-то так должно работать :

class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField()
    password = serializers.CharField()

    def to_internal_value(self, data):
        return data["request"]

    def validate(self, attrs):
        user = authenticate(username=attrs['email'], password=attrs['password'])
        if not user:
            raise serializers.ValidationError('Incorrect email or password.')
        if not user.is_active:
            raise serializers.ValidationError('User is disabled.')
        return user
...