Django rest framework 可以使用DRF中的super()更改方法中间的代码字符串

Django rest framework 可以使用DRF中的super()更改方法中间的代码字符串,django-rest-framework,Django Rest Framework,我想对以下序列化程序进行子类化: User = get_user_model() class UidAndTokenSerializer(serializers.Serializer): uid = serializers.CharField() token = serializers.CharField() default_error_messages = { "invalid_token": settings.CONSTANTS.message

我想对以下序列化程序进行子类化:

User = get_user_model()



class UidAndTokenSerializer(serializers.Serializer):
    uid = serializers.CharField()
    token = serializers.CharField()

    default_error_messages = {
        "invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
        "invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
    }

    def validate(self, attrs):
        validated_data = super().validate(attrs)

        # uid validation have to be here, because validate_<field_name>
        # doesn't work with modelserializer
        try:
            uid = utils.decode_uid(self.initial_data.get("uid", ""))
            self.user = User.objects.get(pk=uid)
        except (User.DoesNotExist, ValueError, TypeError, OverflowError):
            key_error = "invalid_uid"
            raise ValidationError(
                {"uid": [self.error_messages[key_error]]}, code=key_error
            )

        is_token_valid = self.context["view"].token_generator.check_token(
            self.user, self.initial_data.get("token", "")
        )
        if is_token_valid:
            return validated_data
        else:
            key_error = "invalid_token"
            raise ValidationError(
                {"token": [self.error_messages[key_error]]}, code=key_error
            )

有没有办法用
super()
来实现这一点,而不是将整个内容从超类复制粘贴到子类? 非常感谢。 我现在做的,有点粗略

class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):

    def validate(self, attrs):
        User = get_user_model()
        User.objects = User._default_manager
        attrs = super().validate(attrs)
        if not self.user.deleted:
            raise serializers.ValidationError(
                *error_codes.NOT_SOFT_DELETED
            )
        return attrs


它可以工作,但可能很危险。

您可以定义特殊的方法来获取用户实例:



class UidAndTokenSerializer(serializers.Serializer):
    uid = serializers.CharField()
    token = serializers.CharField()

    default_error_messages = {
        "invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
        "invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
    }

    def _get_user(self, uid):
        return get_user_model().objects.get(pk=uid)

    def validate(self, attrs):
        validated_data = super().validate(attrs)

        # uid validation have to be here, because validate_<field_name>
        # doesn't work with modelserializer
        try:
            uid = utils.decode_uid(self.initial_data.get("uid", ""))
            self.user = self._get_user(uid=uid)
        except (User.DoesNotExist, ValueError, TypeError, OverflowError):
            key_error = "invalid_uid"
            raise ValidationError(
                {"uid": [self.error_messages[key_error]]}, code=key_error
            )

        is_token_valid = self.context["view"].token_generator.check_token(
            self.user, self.initial_data.get("token", "")
        )
        if is_token_valid:
            return validated_data
        else:
            key_error = "invalid_token"
            raise ValidationError(
                {"token": [self.error_messages[key_error]]}, code=key_error
            )


如果没有这些危险的与manager共舞的话,问题在于超类在第三部分包的源代码中。我不能修改it@AlekseiKhatkevich然后创建自己的基本序列化程序类,重写validate方法和add _get_user方法
class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):

    def validate(self, attrs):
        User = get_user_model()
        User.objects = User._default_manager
        attrs = super().validate(attrs)
        if not self.user.deleted:
            raise serializers.ValidationError(
                *error_codes.NOT_SOFT_DELETED
            )
        return attrs



class UidAndTokenSerializer(serializers.Serializer):
    uid = serializers.CharField()
    token = serializers.CharField()

    default_error_messages = {
        "invalid_token": settings.CONSTANTS.messages.INVALID_TOKEN_ERROR,
        "invalid_uid": settings.CONSTANTS.messages.INVALID_UID_ERROR,
    }

    def _get_user(self, uid):
        return get_user_model().objects.get(pk=uid)

    def validate(self, attrs):
        validated_data = super().validate(attrs)

        # uid validation have to be here, because validate_<field_name>
        # doesn't work with modelserializer
        try:
            uid = utils.decode_uid(self.initial_data.get("uid", ""))
            self.user = self._get_user(uid=uid)
        except (User.DoesNotExist, ValueError, TypeError, OverflowError):
            key_error = "invalid_uid"
            raise ValidationError(
                {"uid": [self.error_messages[key_error]]}, code=key_error
            )

        is_token_valid = self.context["view"].token_generator.check_token(
            self.user, self.initial_data.get("token", "")
        )
        if is_token_valid:
            return validated_data
        else:
            key_error = "invalid_token"
            raise ValidationError(
                {"token": [self.error_messages[key_error]]}, code=key_error
            )


class CommitUndeleteUserAccountSerializer(UidAndTokenSerializer):
    def _get_user(self, uid):
        return get_user_model()._default_manager.get(pk=uid)

    def validate(self, attrs):
        attrs = super().validate(attrs)
        if not self.user.deleted:
            raise serializers.ValidationError(
                *error_codes.NOT_SOFT_DELETED
            )
        return attrs